mirror of
https://github.com/anyproto/anytype-heart.git
synced 2025-06-09 17:44:59 +09:00
GO-4459 Merge branch 'main' into go-4459-implement-first-stage-of-anytype-rest-api
This commit is contained in:
commit
d2ce601810
385 changed files with 8813 additions and 9833 deletions
176
.github/workflows/perftests.yml
vendored
176
.github/workflows/perftests.yml
vendored
|
@ -2,10 +2,14 @@
|
|||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run-on-runner:
|
||||
description: 'Specify the runner to use'
|
||||
run-on-runner-mac:
|
||||
description: 'Specify the runner to use on MacOS'
|
||||
required: true
|
||||
default: 'ARM64'
|
||||
run-on-runner-win:
|
||||
description: 'Specify the runner to use on Windows'
|
||||
required: true
|
||||
default: 'windows-perftests'
|
||||
perf-test:
|
||||
description: 'Run perf test times'
|
||||
required: true
|
||||
|
@ -17,7 +21,6 @@ on:
|
|||
include:
|
||||
- 'main'
|
||||
|
||||
|
||||
permissions:
|
||||
actions: 'write'
|
||||
contents: 'write'
|
||||
|
@ -25,7 +28,7 @@ permissions:
|
|||
|
||||
name: Perf tests
|
||||
jobs:
|
||||
build:
|
||||
perftests-macos:
|
||||
timeout-minutes: 60
|
||||
runs-on: 'ARM64'
|
||||
steps:
|
||||
|
@ -76,7 +79,7 @@ jobs:
|
|||
RUN_COUNT=${{ github.event.inputs.perf-test }}
|
||||
if [[ "${{ github.event_name }}" == "schedule" ]]; then
|
||||
RUN_COUNT=10
|
||||
fi
|
||||
fi
|
||||
echo $PERF_CONFIG_STAGING > config.json
|
||||
mv .github/staging_fake.yml staging_fake.yml
|
||||
PERF_CONFIG=$PWD/config.json
|
||||
|
@ -97,6 +100,165 @@ jobs:
|
|||
- name: Archive perf tests results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: traces
|
||||
name: traces-macos
|
||||
path: |
|
||||
*.log
|
||||
*.log
|
||||
|
||||
perftests-windows:
|
||||
timeout-minutes: 60
|
||||
runs-on: 'windows-perftests'
|
||||
steps:
|
||||
- name: Install windows utils
|
||||
run: C:\ProgramData\chocolatey\bin\choco install gzip mingw git -y
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
cache: false
|
||||
|
||||
- name: Setup Go env
|
||||
run: |
|
||||
go version
|
||||
echo GOPATH=$(go env GOPATH) >> $env:GITHUB_ENV
|
||||
echo GOBIN=$(go env GOPATH)\bin >> $env:GITHUB_ENV
|
||||
echo $(go env GOPATH)\bin >> $env:GITHUB_PATH
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Set env vars
|
||||
env:
|
||||
UNSPLASH_KEY: ${{ secrets.UNSPLASH_KEY }}
|
||||
INHOUSE_KEY: ${{ secrets.INHOUSE_KEY }}
|
||||
run: |
|
||||
$GIT_SUMMARY = git describe --tags --always
|
||||
echo "FLAGS=-X github.com/anyproto/anytype-heart/util/vcs.GitSummary=$GIT_SUMMARY -X github.com/anyproto/anytype-heart/metrics.DefaultInHouseKey=$env:INHOUSE_KEY -X github.com/anyproto/anytype-heart/util/unsplash.DefaultToken=$env:UNSPLASH_KEY" >> $env:GITHUB_ENV
|
||||
if ($env:GITHUB_EVENT_NAME -eq "workflow_dispatch") {
|
||||
$VERSION = ${{ github.event.inputs.alpha_version }}
|
||||
if (-not $VERSION) {
|
||||
$VERSION = git rev-parse --short HEAD
|
||||
}
|
||||
}
|
||||
if (-not $VERSION) {
|
||||
$VERSION = ($env:GITHUB_REF -split "/")[-1]
|
||||
}
|
||||
echo "VERSION=$VERSION" >> $env:GITHUB_ENV
|
||||
echo "MAVEN_ARTIFACT_VERSION=$VERSION" >> $env:GITHUB_ENV
|
||||
echo "GOPRIVATE=github.com/anyproto" >> $env:GITHUB_ENV
|
||||
echo "$(Get-Location)\deps" >> $env:GITHUB_PATH
|
||||
echo "$env:GOBIN" >> $env:GITHUB_PATH
|
||||
git config --global url."https://${{ secrets.ANYTYPE_PAT }}@github.com/".insteadOf "https://github.com/"
|
||||
|
||||
- name: Go mod download
|
||||
run: |
|
||||
go mod download
|
||||
|
||||
- name: Setup network config
|
||||
env:
|
||||
CUSTOM_NETWORK_FILE: ./core/anytype/config/nodes/custom.yml
|
||||
run: |
|
||||
if (-not $env:ANY_SYNC_NETWORK) {
|
||||
echo "Using the default production Any Sync Network"
|
||||
} elseif (-not (Test-Path $env:ANY_SYNC_NETWORK)) {
|
||||
echo "Network configuration file not found at $env:ANY_SYNC_NETWORK"
|
||||
exit 1
|
||||
} else {
|
||||
echo "Using Any Sync Network configuration at $env:ANY_SYNC_NETWORK"
|
||||
Copy-Item -Path $env:ANY_SYNC_NETWORK -Destination $CUSTOM_NETWORK_FILE -Force
|
||||
}
|
||||
|
||||
- name: Check and download tantivy
|
||||
env:
|
||||
TANTIVY_GO_PATH: ../tantivy-go
|
||||
OUTPUT_DIR: deps/libs
|
||||
REPO: anyproto/tantivy-go
|
||||
run: |
|
||||
$TANTIVY_VERSION = (Get-Content go.mod | Select-String "github.com/anyproto/tantivy-go" | ForEach-Object { ($_ -split " ")[1] }).Trim()
|
||||
|
||||
$TANTIVY_LIBS = @(
|
||||
"windows-amd64.tar.gz"
|
||||
)
|
||||
|
||||
if (-not (Test-Path "$env:OUTPUT_DIR/.verified") -or (Get-Content "$env:OUTPUT_DIR/.verified").Trim() -ne $TANTIVY_VERSION) {
|
||||
if (Test-Path "$env:OUTPUT_DIR") {
|
||||
Remove-Item -Recurse -Force "$env:OUTPUT_DIR/*"
|
||||
}
|
||||
|
||||
if (-not (Test-Path "$env:OUTPUT_DIR")) {
|
||||
New-Item -ItemType Directory -Path "$env:OUTPUT_DIR" | Out-Null
|
||||
}
|
||||
|
||||
foreach ($lib in $TANTIVY_LIBS) {
|
||||
$downloadUrl = "https://github.com/$env:REPO/releases/download/$TANTIVY_VERSION/$lib"
|
||||
$localFilePath = "$env:OUTPUT_DIR/$lib"
|
||||
Invoke-WebRequest -Uri $downloadUrl -OutFile $localFilePath
|
||||
|
||||
$extractDir = "$env:OUTPUT_DIR/$($lib -replace '.tar.gz', '')"
|
||||
if (-not (Test-Path $extractDir)) {
|
||||
New-Item -ItemType Directory -Path $extractDir | Out-Null
|
||||
}
|
||||
tar -C $extractDir -xvzf $localFilePath
|
||||
}
|
||||
|
||||
Get-ChildItem -Path "$env:OUTPUT_DIR" -Filter "*.tar.gz" | Remove-Item -Force
|
||||
Set-Content -Path "$env:OUTPUT_DIR/.verified" -Value $TANTIVY_VERSION
|
||||
echo "Tantivy libraries updated successfully."
|
||||
} else {
|
||||
echo "Tantivy libraries are up to date."
|
||||
}
|
||||
|
||||
- name: Install grpcurl and govvv
|
||||
run: |
|
||||
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
|
||||
go install github.com/ahmetb/govvv@v0.2.0
|
||||
|
||||
- name: Run perf tests
|
||||
run: |
|
||||
echo "Running perf tests in staging mode..."
|
||||
if ($env:GITHUB_EVENT_NAME -eq "schedule") {
|
||||
$RUN_COUNT = 10
|
||||
} elseif ("${{ github.event.inputs.perf-test }}" -ne "") {
|
||||
$RUN_COUNT = "${{ github.event.inputs.perf-test }}"
|
||||
} else {
|
||||
$RUN_COUNT = 10 # default value
|
||||
}
|
||||
echo "Current RUN_COUNT: $RUN_COUNT"
|
||||
echo "Current Github event name: $env:GITHUB_EVENT_NAME"
|
||||
Set-Content -Path config.json -Value $env:PERF_CONFIG_STAGING
|
||||
(Get-Content config.json).Replace('"/Users/user1/account30000"', '"C:/Users/' + $env:USERNAME + '"') | Set-Content -Path config.json
|
||||
Move-Item -Path .\.github\staging_fake.yml -Destination .\staging_fake.yml -Force
|
||||
$PERF_CONFIG = ((Get-Location).Path -replace '\\', '/') + "/config.json"
|
||||
Set-Location cmd\perfstand\account_create
|
||||
$env:CGO_ENABLED = "1"
|
||||
go run main.go $PERF_CONFIG $RUN_COUNT
|
||||
Set-Location ..\account_select
|
||||
go run main.go $PERF_CONFIG $RUN_COUNT
|
||||
echo "Perf test with staging - done"
|
||||
|
||||
echo "Running perf tests in local mode..."
|
||||
Set-Location (Resolve-Path "../../..")
|
||||
Set-Content -Path config.json -Value $env:PERF_CONFIG_LOCAL
|
||||
(Get-Content config.json).Replace('"/Users/user1/account30000"', '"C:/Users/' + $env:USERNAME + '"') | Set-Content -Path config.json
|
||||
Set-Location cmd\perfstand\account_create
|
||||
$env:CGO_ENABLED = "1"
|
||||
go run main.go $PERF_CONFIG $RUN_COUNT
|
||||
Set-Location ..\account_select
|
||||
go run main.go $PERF_CONFIG $RUN_COUNT
|
||||
echo "Perf test in local mode - done"
|
||||
env:
|
||||
PERF_CONFIG_STAGING: ${{ secrets.PERF_CONFIG_STAGING }}
|
||||
PERF_CONFIG_LOCAL: ${{ secrets.PERF_CONFIG_LOCAL }}
|
||||
CH_API_KEY: ${{ secrets.CH_PERF_API_KEY }}
|
||||
|
||||
- name: Clean /tmp
|
||||
run: |
|
||||
echo "Clean workspaces in /Temp"
|
||||
Get-ChildItem "C:/Users/$env:USERNAME/AppData/Local/Temp/" -Directory -Force | Where-Object { $_.Name -like "workspace*" } | ForEach-Object { Remove-Item $_.FullName -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
|
||||
- name: Archive perf tests results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: traces-win
|
||||
path: |
|
||||
*.log
|
||||
|
|
|
@ -43,6 +43,9 @@ packages:
|
|||
github.com/anyproto/anytype-heart/core/block/import/common:
|
||||
interfaces:
|
||||
Converter:
|
||||
github.com/anyproto/anytype-heart/core/block/import/web/parsers:
|
||||
interfaces:
|
||||
Parser:
|
||||
github.com/anyproto/anytype-heart/core/block/restriction:
|
||||
interfaces:
|
||||
Service:
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
|
||||
|
@ -58,10 +59,18 @@ func main() {
|
|||
|
||||
func iterate(prep *input, result internal.PerfResult) error {
|
||||
workspace, err := os.MkdirTemp("", "workspace")
|
||||
prep.Workspace = workspace
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
workspace, err = internal.WinFixPath(workspace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
prep.Workspace = workspace
|
||||
defer os.RemoveAll(workspace)
|
||||
fmt.Println("Created temporary directory:", workspace)
|
||||
|
||||
|
@ -79,7 +88,13 @@ func iterate(prep *input, result internal.PerfResult) error {
|
|||
return err
|
||||
}
|
||||
|
||||
walletStr, err := exec.Command("bash", "-c", internal.GrpcWalletCreate(workspace)).Output()
|
||||
var cmd *exec.Cmd
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd = exec.Command("powershell", "-Command", internal.GrpcWalletCreate(workspace))
|
||||
} else {
|
||||
cmd = exec.Command("bash", "-c", internal.GrpcWalletCreate(workspace))
|
||||
}
|
||||
walletStr, err := cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -80,12 +80,23 @@ func SendResultsToHttp(apiKey string, events []Event) error {
|
|||
}
|
||||
|
||||
func KillServer() error {
|
||||
return ExecuteCommand("kill -9 $(lsof -i :31007 -t) ; echo \"Server killed\"")
|
||||
var cmd string
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd = `(Get-NetTCPConnection -LocalPort 31007 -State Listen | Select-Object -ExpandProperty OwningProcess | ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue }) ; Write-Host "Server killed"`
|
||||
} else {
|
||||
cmd = "kill -9 $(lsof -i :31007 -t) ; echo \"Server killed\""
|
||||
}
|
||||
return ExecuteCommand(cmd)
|
||||
}
|
||||
|
||||
func ExecuteCommand(command string) error {
|
||||
fmt.Println(command)
|
||||
cmd := exec.Command("bash", "-c", command)
|
||||
var cmd *exec.Cmd
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd = exec.Command("powershell", "-Command", command)
|
||||
} else {
|
||||
cmd = exec.Command("bash", "-c", command)
|
||||
}
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err := cmd.Run()
|
||||
|
@ -96,7 +107,10 @@ func ExecuteCommand(command string) error {
|
|||
}
|
||||
|
||||
func UnpackZip(path string, workspace string) error {
|
||||
return ExecuteCommand("unzip -o " + path + " -d " + workspace)
|
||||
if runtime.GOOS == "windows" {
|
||||
return ExecuteCommand("Expand-Archive -Path " + path + " -DestinationPath " + workspace + " -Force")
|
||||
}
|
||||
return ExecuteCommand("unzip -qq -o " + path + " -d " + workspace)
|
||||
}
|
||||
|
||||
func BuildAnytype(err error) error {
|
||||
|
@ -117,6 +131,10 @@ func LoadEnv(env string) (string, error) {
|
|||
return res, nil
|
||||
}
|
||||
|
||||
func WinFixPath(winPath string) (string, error) {
|
||||
return strings.ReplaceAll(winPath, "\\", "/"), nil
|
||||
}
|
||||
|
||||
func SetupWd() (string, error) {
|
||||
err := os.Chdir("../../..")
|
||||
if err != nil {
|
||||
|
@ -128,22 +146,42 @@ func SetupWd() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
getwd, err = WinFixPath(getwd)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("Current working directory:", getwd)
|
||||
return getwd, nil
|
||||
}
|
||||
|
||||
func GrpcWorkspaceOpen(workspace string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"spaceId\":\"` + workspace + `\"}" localhost:31007 anytype.ClientCommands.WorkspaceOpen'`
|
||||
}
|
||||
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
|
||||
"spaceId": "` + workspace + `"
|
||||
}' localhost:31007 anytype.ClientCommands.WorkspaceOpen`
|
||||
}
|
||||
|
||||
func GrpcWorkspaceCreate() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{}" localhost:31007 anytype.ClientCommands.WorkspaceCreate'`
|
||||
}
|
||||
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
|
||||
}' localhost:31007 anytype.ClientCommands.WorkspaceCreate`
|
||||
}
|
||||
|
||||
func GrpcAccountSelect(accHash, workspace, networkMode, staging string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
staging, err := WinFixPath(staging)
|
||||
if err != nil {
|
||||
return "Error: " + err.Error()
|
||||
}
|
||||
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"id\":\"` + accHash + `\",\"rootPath\":\"` + workspace + `\",\"disableLocalNetworkSync\":false,\"networkMode\":` + networkMode + `,\"networkCustomConfigFilePath\":\"` + staging + `\"}" localhost:31007 anytype.ClientCommands.AccountSelect'`
|
||||
}
|
||||
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
|
||||
"id": "` + accHash + `",
|
||||
"rootPath": "` + workspace + `",
|
||||
|
@ -154,12 +192,18 @@ func GrpcAccountSelect(accHash, workspace, networkMode, staging string) string {
|
|||
}
|
||||
|
||||
func GrpcWalletCreateSession(mnemonic string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"mnemonic\":\"` + mnemonic + `\"}" localhost:31007 anytype.ClientCommands.WalletCreateSession'`
|
||||
}
|
||||
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
|
||||
"mnemonic": "` + mnemonic + `"
|
||||
}' localhost:31007 anytype.ClientCommands.WalletCreateSession`
|
||||
}
|
||||
|
||||
func GrpcWalletRecover(workspace, mnemonic string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"rootPath\":\"` + workspace + `\",\"mnemonic\":\"` + mnemonic + `\"}" localhost:31007 anytype.ClientCommands.WalletRecover'`
|
||||
}
|
||||
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
|
||||
"rootPath": "` + workspace + `",
|
||||
"mnemonic": "` + mnemonic + `"
|
||||
|
@ -167,12 +211,22 @@ func GrpcWalletRecover(workspace, mnemonic string) string {
|
|||
}
|
||||
|
||||
func GrpcWalletCreate(workspace string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"rootPath\":\"` + workspace + `\"}" localhost:31007 anytype.ClientCommands.WalletCreate'`
|
||||
}
|
||||
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
|
||||
"rootPath": "` + workspace + `"
|
||||
}' localhost:31007 anytype.ClientCommands.WalletCreate`
|
||||
}
|
||||
|
||||
func GrpcAccountCreate(workspace, networkMode, staging string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
staging, err := WinFixPath(staging)
|
||||
if err != nil {
|
||||
return "Error: " + err.Error()
|
||||
}
|
||||
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"icon\":13,\"networkMode\":` + networkMode + `,\"storePath\":\"` + workspace + `\",\"networkCustomConfigFilePath\":\"` + staging + `\"}" localhost:31007 anytype.ClientCommands.AccountCreate'`
|
||||
}
|
||||
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
|
||||
"icon": 13,
|
||||
"networkMode": ` + networkMode + `,
|
||||
|
@ -182,6 +236,9 @@ func GrpcAccountCreate(workspace, networkMode, staging string) string {
|
|||
}
|
||||
|
||||
func GrpcInitialSetParameters() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"platform\":\"test\",\"version\":\"0.0.0-test\"}" localhost:31007 anytype.ClientCommands.InitialSetParameters'`
|
||||
}
|
||||
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
|
||||
"platform": "test",
|
||||
"version": "0.0.0-test"
|
||||
|
@ -189,7 +246,12 @@ func GrpcInitialSetParameters() string {
|
|||
}
|
||||
|
||||
func StartAnytypeBackground() error {
|
||||
runServer := exec.Command("./dist/server")
|
||||
var runServer *exec.Cmd
|
||||
if runtime.GOOS == "windows" {
|
||||
runServer = exec.Command("./dist/server.exe")
|
||||
} else {
|
||||
runServer = exec.Command("./dist/server")
|
||||
}
|
||||
runServer.Stdout = os.Stdout
|
||||
runServer.Stderr = os.Stderr
|
||||
runServer.Env = append(os.Environ(), `ANYPROF=:6060`)
|
||||
|
@ -200,7 +262,15 @@ func StartAnytypeBackground() error {
|
|||
|
||||
// Wait for the server to start
|
||||
for {
|
||||
err = ExecuteCommand(`pids=$(lsof -i :31007 -t) && [ -n "$pids" ] && echo "Found process: $pids" || { echo "No process found"; exit 1; }`)
|
||||
var cmd string
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd = `$pids = (Get-NetTCPConnection -LocalPort 31007 -State Listen -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess); if ($pids) { Write-Output "Found process: $pids" } else { Write-Output "No process found"; exit 1 }`
|
||||
} else {
|
||||
cmd = `pids=$(lsof -i :31007 -t) && [ -n "$pids" ] && echo "Found process: $pids" || { echo "No process found"; exit 1; }`
|
||||
}
|
||||
|
||||
err = ExecuteCommand(cmd)
|
||||
|
||||
if err == nil {
|
||||
break
|
||||
} else {
|
||||
|
@ -466,8 +536,18 @@ func Prepare[T BasicInputtable](prep T, f func(T) error) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Created temporary directory:", workspace)
|
||||
prep.SetWorkspace(workspace)
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
winWorkspace, err := WinFixPath(workspace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Created temporary directory:", winWorkspace)
|
||||
prep.SetWorkspace(winWorkspace)
|
||||
} else {
|
||||
fmt.Println("Created temporary directory:", workspace)
|
||||
prep.SetWorkspace(workspace)
|
||||
}
|
||||
|
||||
_, err = SetupWd()
|
||||
if err != nil {
|
||||
|
@ -486,10 +566,29 @@ func Prepare[T BasicInputtable](prep T, f func(T) error) error {
|
|||
}
|
||||
}
|
||||
|
||||
err = BuildAnytype(err)
|
||||
if err != nil {
|
||||
return err
|
||||
if runtime.GOOS == "windows" {
|
||||
fmt.Printf("Build GRPC server on Windows...")
|
||||
command := `
|
||||
$Env:GOOS="windows";
|
||||
$Env:GOARCH="amd64";
|
||||
$Env:CGO_ENABLED="1";
|
||||
$Env:CC="x86_64-w64-mingw32-gcc";
|
||||
$Env:CXX="x86_64-w64-mingw32-g++";
|
||||
go build -o dist/server.exe -ldflags "$env:FLAGS -linkmode external -extldflags=-static" --tags "noauth nosigar nowatchdog" $env:BUILD_FLAGS github.com/anyproto/anytype-heart/cmd/grpcserver
|
||||
`
|
||||
err := ExecuteCommand(command)
|
||||
if err != nil {
|
||||
fmt.Printf("Error on building: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Build completed successfully")
|
||||
}
|
||||
} else {
|
||||
err = BuildAnytype(err)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ func collectUseCaseInfo(files []*zip.File, fileName string) (info *useCaseInfo,
|
|||
key := strings.TrimPrefix(uk, addr.RelationKeyToIdPrefix)
|
||||
info.relations[id] = domain.RelationKey(key)
|
||||
format := pbtypes.GetInt64(snapshot.Snapshot.Data.Details, bundle.RelationKeyRelationFormat.String())
|
||||
if !bundle.HasRelation(key) {
|
||||
if !bundle.HasRelation(domain.RelationKey(key)) {
|
||||
info.customTypesAndRelations[key] = customInfo{id: id, isUsed: false, relationFormat: model.RelationFormat(format)}
|
||||
}
|
||||
case model.SmartBlockType_STType:
|
||||
|
@ -259,7 +259,7 @@ func collectUseCaseInfo(files []*zip.File, fileName string) (info *useCaseInfo,
|
|||
key := strings.TrimPrefix(id, addr.RelationKeyToIdPrefix)
|
||||
info.relations[id] = domain.RelationKey(key)
|
||||
format := pbtypes.GetInt64(snapshot.Snapshot.Data.Details, bundle.RelationKeyRelationFormat.String())
|
||||
if !bundle.HasRelation(key) {
|
||||
if !bundle.HasRelation(domain.RelationKey(key)) {
|
||||
info.customTypesAndRelations[key] = customInfo{id: id, isUsed: false, relationFormat: model.RelationFormat(format)}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/widget"
|
||||
|
@ -44,7 +45,7 @@ func validateRelationLinks(s *pb.SnapshotWithType, info *useCaseInfo) (err error
|
|||
id := pbtypes.GetString(s.Snapshot.Data.Details, bundle.RelationKeyId.String())
|
||||
linksToDelete := make([]keyWithIndex, 0)
|
||||
for i, rel := range s.Snapshot.Data.RelationLinks {
|
||||
if bundle.HasRelation(rel.Key) {
|
||||
if bundle.HasRelation(domain.RelationKey(rel.Key)) {
|
||||
continue
|
||||
}
|
||||
if _, found := info.customTypesAndRelations[rel.Key]; found {
|
||||
|
@ -123,7 +124,7 @@ func validateDetails(s *pb.SnapshotWithType, info *useCaseInfo) (err error) {
|
|||
|
||||
values := pbtypes.GetStringListValue(v)
|
||||
for _, val := range values {
|
||||
if bundle.HasRelation(strings.TrimPrefix(val, addr.RelationKeyToIdPrefix)) ||
|
||||
if bundle.HasRelation(domain.RelationKey(strings.TrimPrefix(val, addr.RelationKeyToIdPrefix))) ||
|
||||
bundle.HasObjectTypeByKey(domain.TypeKey(strings.TrimPrefix(val, addr.ObjectTypeKeyToIdPrefix))) || val == addr.AnytypeProfileId {
|
||||
continue
|
||||
}
|
||||
|
@ -213,6 +214,39 @@ func validateBlockLinks(s *pb.SnapshotWithType, info *useCaseInfo) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
func validateFileKeys(s *pb.SnapshotWithType, _ *useCaseInfo) (err error) {
|
||||
id := pbtypes.GetString(s.Snapshot.Data.Details, bundle.RelationKeyId.String())
|
||||
for _, r := range s.Snapshot.Data.RelationLinks {
|
||||
if r.Format == model.RelationFormat_file || r.Key == bundle.RelationKeyCoverId.String() {
|
||||
for _, hash := range pbtypes.GetStringList(s.Snapshot.GetData().GetDetails(), r.Key) {
|
||||
if r.Format != model.RelationFormat_file {
|
||||
_, err := cid.Parse(hash)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if !snapshotHasKeyForHash(s, hash) {
|
||||
err = multierror.Append(err, fmt.Errorf("object '%s' has file detail '%s' has hash '%s' which keys are not in the snapshot", id, r.Key, hash))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, b := range s.Snapshot.Data.Blocks {
|
||||
if v, ok := simple.New(b).(simple.FileHashes); ok {
|
||||
hashes := v.FillFileHashes([]string{})
|
||||
if len(hashes) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, hash := range hashes {
|
||||
if !snapshotHasKeyForHash(s, hash) {
|
||||
err = multierror.Append(err, fmt.Errorf("file block '%s' of object '%s' has hash '%s' which keys are not in the snapshot", b.Id, id, hash))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func validateDeleted(s *pb.SnapshotWithType, _ *useCaseInfo) error {
|
||||
id := pbtypes.GetString(s.Snapshot.Data.Details, bundle.RelationKeyId.String())
|
||||
|
||||
|
@ -240,7 +274,7 @@ func validateRelationOption(s *pb.SnapshotWithType, info *useCaseInfo) error {
|
|||
}
|
||||
|
||||
key := pbtypes.GetString(s.Snapshot.Data.Details, bundle.RelationKeyRelationKey.String())
|
||||
if bundle.HasRelation(key) {
|
||||
if bundle.HasRelation(domain.RelationKey(key)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -261,6 +295,15 @@ func getRelationLinkByKey(links []*model.RelationLink, key string) *model.Relati
|
|||
return nil
|
||||
}
|
||||
|
||||
func snapshotHasKeyForHash(s *pb.SnapshotWithType, hash string) bool {
|
||||
for _, k := range s.Snapshot.FileKeys {
|
||||
if k.Hash == hash && len(k.Keys) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isLinkRelation(k string) bool {
|
||||
return k == bundle.RelationKeyLinks.String() || k == bundle.RelationKeySourceObject.String() || k == bundle.RelationKeyBacklinks.String()
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/anyproto/any-sync/coordinator/coordinatorproto"
|
||||
"github.com/anyproto/any-sync/nodeconf"
|
||||
"github.com/anyproto/any-sync/util/crypto"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/anytype/account"
|
||||
|
@ -27,7 +26,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/space"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/space/techspace"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
const CName = "common.acl.aclservice"
|
||||
|
@ -368,10 +366,10 @@ func (a *aclService) Join(ctx context.Context, spaceId, networkId string, invite
|
|||
if err != nil {
|
||||
return convertedOrInternalError("join space", err)
|
||||
}
|
||||
err = a.spaceService.TechSpace().SpaceViewSetData(ctx, spaceId, &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String(invitePayload.SpaceName),
|
||||
bundle.RelationKeyIconImage.String(): pbtypes.String(invitePayload.SpaceIconCid),
|
||||
}})
|
||||
err = a.spaceService.TechSpace().SpaceViewSetData(ctx, spaceId,
|
||||
domain.NewDetails().
|
||||
SetString(bundle.RelationKeyName, invitePayload.SpaceName).
|
||||
SetString(bundle.RelationKeyIconImage, invitePayload.SpaceIconCid))
|
||||
if err != nil {
|
||||
return convertedOrInternalError("set space data", err)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
)
|
||||
|
||||
type Profile struct {
|
||||
|
@ -36,20 +37,9 @@ func (s *service) ProfileInfo() (Profile, error) {
|
|||
if err != nil {
|
||||
return profile, err
|
||||
}
|
||||
|
||||
if profileDetails != nil && profileDetails.Details != nil && profileDetails.Details.Fields != nil {
|
||||
for _, s := range []struct {
|
||||
field string
|
||||
receiver *string
|
||||
}{
|
||||
{"name", &profile.Name},
|
||||
{"iconImage", &profile.IconImage},
|
||||
{"iconColor", &profile.IconColor},
|
||||
} {
|
||||
if value, ok := profileDetails.Details.Fields[s.field]; ok {
|
||||
*s.receiver = value.GetStringValue()
|
||||
}
|
||||
}
|
||||
if profileDetails != nil {
|
||||
profile.Name = profileDetails.GetString(bundle.RelationKeyName)
|
||||
profile.IconImage = profileDetails.GetString(bundle.RelationKeyIconImage)
|
||||
}
|
||||
|
||||
return profile, nil
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/anytype/account"
|
||||
"github.com/anyproto/anytype-heart/core/anytype/config"
|
||||
"github.com/anyproto/anytype-heart/core/block"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/block/detailservice"
|
||||
"github.com/anyproto/anytype-heart/core/domain/objectorigin"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
|
@ -19,7 +20,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/core"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func (s *Service) AccountCreate(ctx context.Context, req *pb.RpcAccountCreateRequest) (*model.Account, error) {
|
||||
|
@ -115,17 +115,17 @@ func (s *Service) setAccountAndProfileDetails(ctx context.Context, req *pb.RpcAc
|
|||
newAcc.Info.AccountSpaceId = spaceService.FirstCreatedSpaceId()
|
||||
|
||||
bs := s.app.MustComponent(block.CName).(*block.Service)
|
||||
commonDetails := []*model.Detail{
|
||||
commonDetails := []domain.Detail{
|
||||
{
|
||||
Key: bundle.RelationKeyName.String(),
|
||||
Value: pbtypes.String(req.Name),
|
||||
Key: bundle.RelationKeyName,
|
||||
Value: domain.String(req.Name),
|
||||
},
|
||||
{
|
||||
Key: bundle.RelationKeyIconOption.String(),
|
||||
Value: pbtypes.Int64(req.Icon),
|
||||
Key: bundle.RelationKeyIconOption,
|
||||
Value: domain.Int64(req.Icon),
|
||||
},
|
||||
}
|
||||
profileDetails := make([]*model.Detail, 0)
|
||||
profileDetails := make([]domain.Detail, 0)
|
||||
profileDetails = append(profileDetails, commonDetails...)
|
||||
|
||||
if req.GetAvatarLocalPath() != "" {
|
||||
|
@ -140,9 +140,9 @@ func (s *Service) setAccountAndProfileDetails(ctx context.Context, req *pb.RpcAc
|
|||
if err != nil {
|
||||
log.Warnf("can't add avatar: %v", err)
|
||||
} else {
|
||||
profileDetails = append(profileDetails, &model.Detail{
|
||||
Key: bundle.RelationKeyIconImage.String(),
|
||||
Value: pbtypes.String(hash),
|
||||
profileDetails = append(profileDetails, domain.Detail{
|
||||
Key: bundle.RelationKeyIconImage,
|
||||
Value: domain.String(hash),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,17 +17,16 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/anytype/account"
|
||||
"github.com/anyproto/anytype-heart/core/anytype/config"
|
||||
"github.com/anyproto/anytype-heart/core/block/detailservice"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/metrics"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/core"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space"
|
||||
"github.com/anyproto/anytype-heart/util/anyerror"
|
||||
"github.com/anyproto/anytype-heart/util/builtinobjects"
|
||||
"github.com/anyproto/anytype-heart/util/constant"
|
||||
"github.com/anyproto/anytype-heart/util/metricsid"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -188,25 +187,25 @@ func (s *Service) setDetails(profile *pb.Profile, icon int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func buildDetails(profile *pb.Profile, icon int64) (profileDetails []*model.Detail, accountDetails []*model.Detail) {
|
||||
profileDetails = []*model.Detail{{
|
||||
Key: bundle.RelationKeyName.String(),
|
||||
Value: pbtypes.String(profile.Name),
|
||||
func buildDetails(profile *pb.Profile, icon int64) (profileDetails []domain.Detail, accountDetails []domain.Detail) {
|
||||
profileDetails = []domain.Detail{{
|
||||
Key: bundle.RelationKeyName,
|
||||
Value: domain.String(profile.Name),
|
||||
}}
|
||||
if profile.Avatar == "" {
|
||||
profileDetails = append(profileDetails, &model.Detail{
|
||||
Key: bundle.RelationKeyIconOption.String(),
|
||||
Value: pbtypes.Int64(icon),
|
||||
profileDetails = append(profileDetails, domain.Detail{
|
||||
Key: bundle.RelationKeyIconOption,
|
||||
Value: domain.Int64(icon),
|
||||
})
|
||||
} else {
|
||||
profileDetails = append(profileDetails, &model.Detail{
|
||||
Key: bundle.RelationKeyIconImage.String(),
|
||||
Value: pbtypes.String(profile.Avatar),
|
||||
profileDetails = append(profileDetails, domain.Detail{
|
||||
Key: bundle.RelationKeyIconImage,
|
||||
Value: domain.String(profile.Avatar),
|
||||
})
|
||||
}
|
||||
accountDetails = []*model.Detail{{
|
||||
Key: bundle.RelationKeyIconOption.String(),
|
||||
Value: pbtypes.Int64(icon),
|
||||
accountDetails = []domain.Detail{{
|
||||
Key: bundle.RelationKeyIconOption,
|
||||
Value: domain.Int64(icon),
|
||||
}}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package application
|
|||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/event"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/core"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
|
@ -18,20 +19,13 @@ func (s *Service) AccountRecover() error {
|
|||
return errors.Join(ErrBadInput, err)
|
||||
}
|
||||
|
||||
event := &pb.Event{
|
||||
Messages: []*pb.EventMessage{
|
||||
{
|
||||
Value: &pb.EventMessageValueOfAccountShow{
|
||||
AccountShow: &pb.EventAccountShow{
|
||||
Account: &model.Account{
|
||||
Id: res.Identity.GetPublic().Account(),
|
||||
},
|
||||
},
|
||||
},
|
||||
s.eventSender.Broadcast(event.NewEventSingleMessage("", &pb.EventMessageValueOfAccountShow{
|
||||
AccountShow: &pb.EventAccountShow{
|
||||
Account: &model.Account{
|
||||
Id: res.Identity.GetPublic().Account(),
|
||||
},
|
||||
},
|
||||
}
|
||||
s.eventSender.Broadcast(event)
|
||||
}))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/event"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
walletComp "github.com/anyproto/anytype-heart/core/wallet"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
|
@ -73,18 +74,12 @@ func (s *Service) LinkLocalStartNewChallenge(clientInfo *pb.EventAccountLinkChal
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
s.eventSender.Broadcast(&pb.Event{
|
||||
Messages: []*pb.EventMessage{
|
||||
{
|
||||
Value: &pb.EventMessageValueOfAccountLinkChallenge{
|
||||
AccountLinkChallenge: &pb.EventAccountLinkChallenge{
|
||||
Challenge: value,
|
||||
ClientInfo: clientInfo,
|
||||
},
|
||||
},
|
||||
},
|
||||
s.eventSender.Broadcast(event.NewEventSingleMessage("", &pb.EventMessageValueOfAccountLinkChallenge{
|
||||
AccountLinkChallenge: &pb.EventAccountLinkChallenge{
|
||||
Challenge: value,
|
||||
ClientInfo: clientInfo,
|
||||
},
|
||||
})
|
||||
}))
|
||||
return id, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -57,16 +57,16 @@ func (mw *Middleware) BlockLinkCreateWithObject(cctx context.Context, req *pb.Rp
|
|||
}
|
||||
var (
|
||||
id, targetId string
|
||||
objectDetails *types.Struct
|
||||
objectDetails *domain.Details
|
||||
)
|
||||
err := mw.doBlockService(func(bs *block.Service) (err error) {
|
||||
id, targetId, objectDetails, err = bs.CreateLinkToTheNewObject(cctx, ctx, req)
|
||||
return
|
||||
})
|
||||
if err != nil {
|
||||
return response(pb.RpcBlockLinkCreateWithObjectResponseError_UNKNOWN_ERROR, "", "", objectDetails, err)
|
||||
return response(pb.RpcBlockLinkCreateWithObjectResponseError_UNKNOWN_ERROR, "", "", nil, err)
|
||||
}
|
||||
return response(pb.RpcBlockLinkCreateWithObjectResponseError_NULL, id, targetId, objectDetails, nil)
|
||||
return response(pb.RpcBlockLinkCreateWithObjectResponseError_NULL, id, targetId, objectDetails.ToProto(), nil)
|
||||
}
|
||||
|
||||
func (mw *Middleware) ObjectOpen(cctx context.Context, req *pb.RpcObjectOpenRequest) *pb.RpcObjectOpenResponse {
|
||||
|
|
|
@ -9,13 +9,13 @@ import (
|
|||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/app/ocache"
|
||||
"github.com/cheggaaa/mb"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/block/object/idresolver"
|
||||
"github.com/anyproto/anytype-heart/core/block/source"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
|
@ -24,7 +24,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/threads"
|
||||
"github.com/anyproto/anytype-heart/space"
|
||||
"github.com/anyproto/anytype-heart/util/dateutil"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
|
@ -218,11 +217,11 @@ func (w *watcher) updateBackLinksInObject(id string, backlinksUpdate *backLinksU
|
|||
}
|
||||
spaceDerivedIds := spc.DerivedIDs()
|
||||
|
||||
updateBacklinks := func(current *types.Struct, backlinksChange *backLinksUpdate) (*types.Struct, bool, error) {
|
||||
if current == nil || current.Fields == nil {
|
||||
updateBacklinks := func(current *domain.Details, backlinksChange *backLinksUpdate) (*domain.Details, bool, error) {
|
||||
if current == nil {
|
||||
return nil, false, nil
|
||||
}
|
||||
backlinks := pbtypes.GetStringList(current, bundle.RelationKeyBacklinks.String())
|
||||
backlinks := current.GetStringList(bundle.RelationKeyBacklinks)
|
||||
|
||||
for _, removed := range backlinksChange.removed {
|
||||
backlinks = slice.Remove(backlinks, removed)
|
||||
|
@ -239,14 +238,14 @@ func (w *watcher) updateBackLinksInObject(id string, backlinksUpdate *backLinksU
|
|||
return shouldIndexBacklinks(spaceDerivedIds, s)
|
||||
})
|
||||
|
||||
current.Fields[bundle.RelationKeyBacklinks.String()] = pbtypes.StringList(backlinks)
|
||||
current.SetStringList(bundle.RelationKeyBacklinks, backlinks)
|
||||
return current, true, nil
|
||||
}
|
||||
|
||||
if shouldIndexBacklinks(spaceDerivedIds, id) {
|
||||
// filter-out backlinks in system objects
|
||||
err = spc.DoLockedIfNotExists(id, func() error {
|
||||
return w.store.SpaceIndex(spaceId).ModifyObjectDetails(id, func(details *types.Struct) (*types.Struct, bool, error) {
|
||||
return w.store.SpaceIndex(spaceId).ModifyObjectDetails(id, func(details *domain.Details) (*domain.Details, bool, error) {
|
||||
return updateBacklinks(details, backlinksUpdate)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -11,13 +11,13 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/object/idresolver/mock_idresolver"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/threads"
|
||||
"github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace"
|
||||
"github.com/anyproto/anytype-heart/space/mock_space"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
const spaceId = "spc1"
|
||||
|
@ -132,13 +132,13 @@ func TestWatcher_updateAccumulatedBacklinks(t *testing.T) {
|
|||
f.resolver.EXPECT().ResolveSpaceID(mock.Anything).Return(spaceId, nil)
|
||||
|
||||
f.store.AddObjects(t, spaceId, []spaceindex.TestObject{{
|
||||
bundle.RelationKeyId: pbtypes.String("obj1"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyBacklinks: pbtypes.StringList([]string{"obj4", "obj5", "obj6"}),
|
||||
bundle.RelationKeyId: domain.String("obj1"),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyBacklinks: domain.StringList([]string{"obj4", "obj5", "obj6"}),
|
||||
}, {
|
||||
bundle.RelationKeyId: pbtypes.String("obj3"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyBacklinks: pbtypes.StringList([]string{"obj1", "obj2", "obj4"}),
|
||||
bundle.RelationKeyId: domain.String("obj3"),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyBacklinks: domain.StringList([]string{"obj1", "obj2", "obj4"}),
|
||||
}})
|
||||
|
||||
spc := mock_clientspace.NewMockSpace(t)
|
||||
|
@ -174,9 +174,9 @@ func TestWatcher_updateAccumulatedBacklinks(t *testing.T) {
|
|||
// then
|
||||
details, err := f.store.SpaceIndex(spaceId).GetDetails("obj1")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{"obj6", "obj2", "obj3"}, pbtypes.GetStringList(details.Details, bundle.RelationKeyBacklinks.String()))
|
||||
assert.Equal(t, []string{"obj6", "obj2", "obj3"}, details.GetStringList(bundle.RelationKeyBacklinks))
|
||||
details, err = f.store.SpaceIndex(spaceId).GetDetails("obj3")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{"obj2"}, pbtypes.GetStringList(details.Details, bundle.RelationKeyBacklinks.String()))
|
||||
assert.Equal(t, []string{"obj2"}, details.GetStringList(bundle.RelationKeyBacklinks))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/block/import/markdown/anymark"
|
||||
|
@ -31,7 +30,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space"
|
||||
"github.com/anyproto/anytype-heart/util/linkpreview"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/uri"
|
||||
)
|
||||
|
||||
|
@ -41,8 +39,8 @@ const CName = "bookmark"
|
|||
type ContentFuture func() *bookmark.ObjectContent
|
||||
|
||||
type Service interface {
|
||||
CreateObjectAndFetch(ctx context.Context, spaceId string, details *types.Struct) (objectID string, newDetails *types.Struct, err error)
|
||||
CreateBookmarkObject(ctx context.Context, spaceId string, details *types.Struct, getContent ContentFuture) (objectId string, newDetails *types.Struct, err error)
|
||||
CreateObjectAndFetch(ctx context.Context, spaceId string, details *domain.Details) (objectID string, newDetails *domain.Details, err error)
|
||||
CreateBookmarkObject(ctx context.Context, spaceId string, details *domain.Details, getContent ContentFuture) (objectId string, newDetails *domain.Details, err error)
|
||||
UpdateObject(objectId string, getContent *bookmark.ObjectContent) error
|
||||
// TODO Maybe Fetch and FetchBookmarkContent do the same thing differently?
|
||||
FetchAsync(spaceID string, blockID string, params bookmark.FetchParams)
|
||||
|
@ -53,11 +51,11 @@ type Service interface {
|
|||
}
|
||||
|
||||
type ObjectCreator interface {
|
||||
CreateSmartBlockFromState(ctx context.Context, spaceID string, objectTypeKeys []domain.TypeKey, createState *state.State) (id string, newDetails *types.Struct, err error)
|
||||
CreateSmartBlockFromState(ctx context.Context, spaceID string, objectTypeKeys []domain.TypeKey, createState *state.State) (id string, newDetails *domain.Details, err error)
|
||||
}
|
||||
|
||||
type DetailsSetter interface {
|
||||
SetDetails(ctx session.Context, objectId string, details []*model.Detail) (err error)
|
||||
SetDetails(ctx session.Context, objectId string, details []domain.Detail) (err error)
|
||||
}
|
||||
|
||||
type service struct {
|
||||
|
@ -92,9 +90,9 @@ func (s *service) Name() (name string) {
|
|||
var log = logging.Logger("anytype-mw-bookmark")
|
||||
|
||||
func (s *service) CreateObjectAndFetch(
|
||||
ctx context.Context, spaceId string, details *types.Struct,
|
||||
) (objectID string, newDetails *types.Struct, err error) {
|
||||
source := pbtypes.GetString(details, bundle.RelationKeySource.String())
|
||||
ctx context.Context, spaceId string, details *domain.Details,
|
||||
) (objectID string, newDetails *domain.Details, err error) {
|
||||
source := details.GetString(bundle.RelationKeySource)
|
||||
var res ContentFuture
|
||||
if source != "" {
|
||||
u, err := uri.NormalizeURI(source)
|
||||
|
@ -111,9 +109,9 @@ func (s *service) CreateObjectAndFetch(
|
|||
}
|
||||
|
||||
func (s *service) CreateBookmarkObject(
|
||||
ctx context.Context, spaceID string, details *types.Struct, getContent ContentFuture,
|
||||
) (objectId string, objectDetails *types.Struct, err error) {
|
||||
if details == nil || details.Fields == nil {
|
||||
ctx context.Context, spaceID string, details *domain.Details, getContent ContentFuture,
|
||||
) (objectId string, objectDetails *domain.Details, err error) {
|
||||
if details == nil {
|
||||
return "", nil, fmt.Errorf("empty details")
|
||||
}
|
||||
|
||||
|
@ -125,25 +123,25 @@ func (s *service) CreateBookmarkObject(
|
|||
if err != nil {
|
||||
return "", nil, fmt.Errorf("get bookmark type id: %w", err)
|
||||
}
|
||||
url := pbtypes.GetString(details, bundle.RelationKeySource.String())
|
||||
url := details.GetString(bundle.RelationKeySource)
|
||||
|
||||
records, err := s.store.SpaceIndex(spaceID).Query(database.Query{
|
||||
Sorts: []*model.BlockContentDataviewSort{
|
||||
Sorts: []database.SortRequest{
|
||||
{
|
||||
RelationKey: bundle.RelationKeyLastModifiedDate.String(),
|
||||
RelationKey: bundle.RelationKeyLastModifiedDate,
|
||||
Type: model.BlockContentDataviewSort_Desc,
|
||||
},
|
||||
},
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
RelationKey: bundle.RelationKeySource.String(),
|
||||
RelationKey: bundle.RelationKeySource,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(url),
|
||||
Value: domain.String(url),
|
||||
},
|
||||
{
|
||||
RelationKey: bundle.RelationKeyType.String(),
|
||||
RelationKey: bundle.RelationKeyType,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(typeId),
|
||||
Value: domain.String(typeId),
|
||||
},
|
||||
},
|
||||
Limit: 1,
|
||||
|
@ -154,7 +152,7 @@ func (s *service) CreateBookmarkObject(
|
|||
|
||||
if len(records) > 0 {
|
||||
rec := records[0]
|
||||
objectId = rec.Details.Fields[bundle.RelationKeyId.String()].GetStringValue()
|
||||
objectId = rec.Details.GetString(bundle.RelationKeyId)
|
||||
objectDetails = rec.Details
|
||||
} else {
|
||||
creationState := state.NewDoc("", nil).(*state.State)
|
||||
|
@ -183,25 +181,13 @@ func (s *service) CreateBookmarkObject(
|
|||
return objectId, objectDetails, nil
|
||||
}
|
||||
|
||||
func detailsFromContent(content *bookmark.ObjectContent) map[string]*types.Value {
|
||||
return map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String(content.BookmarkContent.Title),
|
||||
bundle.RelationKeyDescription.String(): pbtypes.String(content.BookmarkContent.Description),
|
||||
bundle.RelationKeySource.String(): pbtypes.String(content.BookmarkContent.Url),
|
||||
bundle.RelationKeyPicture.String(): pbtypes.String(content.BookmarkContent.ImageHash),
|
||||
bundle.RelationKeyIconImage.String(): pbtypes.String(content.BookmarkContent.FaviconHash),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) UpdateObject(objectId string, getContent *bookmark.ObjectContent) error {
|
||||
detailsMap := detailsFromContent(getContent)
|
||||
|
||||
details := make([]*model.Detail, 0, len(detailsMap))
|
||||
for k, v := range detailsMap {
|
||||
details = append(details, &model.Detail{
|
||||
Key: k,
|
||||
Value: v,
|
||||
})
|
||||
func (s *service) UpdateObject(objectId string, content *bookmark.ObjectContent) error {
|
||||
details := []domain.Detail{
|
||||
{Key: bundle.RelationKeyName, Value: domain.String(content.BookmarkContent.Title)},
|
||||
{Key: bundle.RelationKeyDescription, Value: domain.String(content.BookmarkContent.Description)},
|
||||
{Key: bundle.RelationKeySource, Value: domain.String(content.BookmarkContent.Url)},
|
||||
{Key: bundle.RelationKeyPicture, Value: domain.String(content.BookmarkContent.ImageHash)},
|
||||
{Key: bundle.RelationKeyIconImage, Value: domain.String(content.BookmarkContent.FaviconHash)},
|
||||
}
|
||||
|
||||
return s.detailsSetter.SetDetails(nil, objectId, details)
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
|
@ -19,7 +18,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace"
|
||||
"github.com/anyproto/anytype-heart/space/mock_space"
|
||||
"github.com/anyproto/anytype-heart/util/linkpreview/mock_linkpreview"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -29,7 +27,7 @@ const (
|
|||
|
||||
type detailsSetter struct{}
|
||||
|
||||
func (ds *detailsSetter) SetDetails(session.Context, string, []*model.Detail) error {
|
||||
func (ds *detailsSetter) SetDetails(session.Context, string, []domain.Detail) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -71,9 +69,9 @@ func TestService_CreateBookmarkObject(t *testing.T) {
|
|||
t.Run("new bookmark object creation", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
details := &types.Struct{Fields: map[string]*types.Value{}}
|
||||
details := domain.NewDetails()
|
||||
fx.creator.EXPECT().CreateSmartBlockFromState(mock.Anything, mock.Anything, mock.Anything, mock.Anything).RunAndReturn(
|
||||
func(_ context.Context, spcId string, keys []domain.TypeKey, state *state.State) (string, *types.Struct, error) {
|
||||
func(_ context.Context, spcId string, keys []domain.TypeKey, state *state.State) (string, *domain.Details, error) {
|
||||
assert.Equal(t, spaceId, spcId)
|
||||
assert.Equal(t, []domain.TypeKey{bundle.TypeKeyBookmark}, keys)
|
||||
assert.Equal(t, details, state.Details())
|
||||
|
@ -93,13 +91,13 @@ func TestService_CreateBookmarkObject(t *testing.T) {
|
|||
// given
|
||||
fx := newFixture(t)
|
||||
url := "https://url.com"
|
||||
details := &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeySource.String(): pbtypes.String(url),
|
||||
}}
|
||||
details := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeySource: domain.String(url),
|
||||
})
|
||||
fx.store.AddObjects(t, "space1", []objectstore.TestObject{{
|
||||
bundle.RelationKeyId: pbtypes.String("bk"),
|
||||
bundle.RelationKeySource: pbtypes.String(url),
|
||||
bundle.RelationKeyType: pbtypes.String(bookmarkId),
|
||||
bundle.RelationKeyId: domain.String("bk"),
|
||||
bundle.RelationKeySource: domain.String(url),
|
||||
bundle.RelationKeyType: domain.String(bookmarkId),
|
||||
}})
|
||||
|
||||
// when
|
||||
|
|
|
@ -4,14 +4,13 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
bookmarksvc "github.com/anyproto/anytype-heart/core/block/bookmark"
|
||||
"github.com/anyproto/anytype-heart/core/block/import"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/logging"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
const CName = "bookmark-importer"
|
||||
|
@ -19,7 +18,7 @@ const CName = "bookmark-importer"
|
|||
var log = logging.Logger("bookmark-importer")
|
||||
|
||||
type Importer interface {
|
||||
ImportWeb(ctx context.Context, req *importer.ImportRequest) (string, *types.Struct, error)
|
||||
ImportWeb(ctx context.Context, req *importer.ImportRequest) (string, *domain.Details, error)
|
||||
}
|
||||
|
||||
type BookmarkImporterDecorator struct {
|
||||
|
@ -38,8 +37,8 @@ func (bd *BookmarkImporterDecorator) Init(a *app.App) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (bd *BookmarkImporterDecorator) CreateBookmarkObject(ctx context.Context, spaceID string, details *types.Struct, getContent bookmarksvc.ContentFuture) (objectId string, newDetails *types.Struct, err error) {
|
||||
url := pbtypes.GetString(details, bundle.RelationKeySource.String())
|
||||
func (bd *BookmarkImporterDecorator) CreateBookmarkObject(ctx context.Context, spaceID string, details *domain.Details, getContent bookmarksvc.ContentFuture) (objectId string, newDetails *domain.Details, err error) {
|
||||
url := details.GetString(bundle.RelationKeySource)
|
||||
if objectId, newDetails, err = bd.Importer.ImportWeb(nil, &importer.ImportRequest{
|
||||
RpcObjectImportRequest: &pb.RpcObjectImportRequest{
|
||||
Params: &pb.RpcObjectImportRequestParamsOfBookmarksParams{BookmarksParams: &pb.RpcObjectImportRequestBookmarksParams{Url: url}},
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/backlinks"
|
||||
|
@ -22,7 +21,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/logging"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/internalflag"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
|
@ -113,7 +111,9 @@ func (s *Service) updateCollection(ctx session.Context, contextID string, modifi
|
|||
lst := s.GetStoreSlice(template.CollectionStoreKey)
|
||||
lst = modifier(lst)
|
||||
s.UpdateStoreSlice(template.CollectionStoreKey, lst)
|
||||
internalflag.Set{}.AddToState(s)
|
||||
// TODO why we're adding empty list of flags?
|
||||
flags := internalflag.Set{}
|
||||
flags.AddToState(s)
|
||||
return nil
|
||||
}, smartblock.KeepInternalFlags)
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ func (s *Service) UnsubscribeFromCollection(collectionID string, subscriptionID
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Service) CreateCollection(details *types.Struct, flags []*model.InternalFlag) (coresb.SmartBlockType, *types.Struct, *state.State, error) {
|
||||
func (s *Service) CreateCollection(details *domain.Details, flags []*model.InternalFlag) (coresb.SmartBlockType, *domain.Details, *state.State, error) {
|
||||
details = internalflag.PutToDetails(details, flags)
|
||||
|
||||
newState := state.NewDoc("", nil).NewState().SetDetails(details)
|
||||
|
@ -228,7 +228,7 @@ func (s *Service) setDefaultObjectTypeToViews(spaceId string, st *state.State) {
|
|||
return
|
||||
}
|
||||
|
||||
setOfValue := pbtypes.GetStringList(st.ParentState().Details(), bundle.RelationKeySetOf.String())
|
||||
setOfValue := st.ParentState().Details().GetStringList(bundle.RelationKeySetOf)
|
||||
if len(setOfValue) == 0 {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import (
|
|||
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
const collectionID = "collectionID"
|
||||
|
@ -163,7 +162,7 @@ func TestSetObjectTypeToViews(t *testing.T) {
|
|||
Views: []*model.BlockContentDataviewView{{Id: viewID1}, {Id: viewID2}},
|
||||
}},
|
||||
}))
|
||||
parent.SetDetail(bundle.RelationKeySetOf.String(), pbtypes.StringList([]string{setOf}))
|
||||
parent.SetDetail(bundle.RelationKeySetOf, domain.StringList([]string{setOf}))
|
||||
return parent.NewState()
|
||||
}
|
||||
|
||||
|
@ -204,8 +203,8 @@ func TestSetObjectTypeToViews(t *testing.T) {
|
|||
s := newFixture(t)
|
||||
s.objectStore.AddObjects(t, "space1", []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String(setOfValue),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String(domain.MustUniqueKey(testCase.sbType, testCase.key).Marshal()),
|
||||
bundle.RelationKeyId: domain.String(setOfValue),
|
||||
bundle.RelationKeyUniqueKey: domain.String(domain.MustUniqueKey(testCase.sbType, testCase.key).Marshal()),
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/cache"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/basic"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
|
@ -17,7 +15,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func (s *Service) ObjectDuplicate(ctx context.Context, id string) (objectID string, err error) {
|
||||
|
@ -32,7 +29,7 @@ func (s *Service) ObjectDuplicate(ctx context.Context, id string) (objectID stri
|
|||
}
|
||||
st = b.NewState().Copy()
|
||||
st.SetLocalDetails(nil)
|
||||
st.SetDetail(bundle.RelationKeySourceObject.String(), pbtypes.String(id))
|
||||
st.SetDetail(bundle.RelationKeySourceObject, domain.String(id))
|
||||
return nil
|
||||
}); err != nil {
|
||||
return
|
||||
|
@ -57,11 +54,11 @@ func (s *Service) CreateWorkspace(ctx context.Context, req *pb.RpcWorkspaceCreat
|
|||
predefinedObjectIDs := newSpace.DerivedIDs()
|
||||
|
||||
err = cache.Do(s, predefinedObjectIDs.Workspace, func(b basic.DetailsSettable) error {
|
||||
details := make([]*model.Detail, 0, len(req.Details.GetFields()))
|
||||
details := make([]domain.Detail, 0, len(req.Details.GetFields()))
|
||||
for k, v := range req.Details.GetFields() {
|
||||
details = append(details, &model.Detail{
|
||||
Key: k,
|
||||
Value: v,
|
||||
details = append(details, domain.Detail{
|
||||
Key: domain.RelationKey(k),
|
||||
Value: domain.ValueFromProto(v),
|
||||
})
|
||||
}
|
||||
return b.SetDetails(nil, details, true)
|
||||
|
@ -81,7 +78,7 @@ func (s *Service) CreateLinkToTheNewObject(
|
|||
ctx context.Context,
|
||||
sctx session.Context,
|
||||
req *pb.RpcBlockLinkCreateWithObjectRequest,
|
||||
) (linkID string, objectId string, objectDetails *types.Struct, err error) {
|
||||
) (linkID string, objectId string, objectDetails *domain.Details, err error) {
|
||||
if req.ContextId == req.TemplateId && req.ContextId != "" {
|
||||
err = fmt.Errorf("unable to create link to template from this template")
|
||||
return
|
||||
|
@ -93,7 +90,7 @@ func (s *Service) CreateLinkToTheNewObject(
|
|||
}
|
||||
|
||||
createReq := objectcreator.CreateObjectRequest{
|
||||
Details: req.Details,
|
||||
Details: domain.NewDetailsFromProto(req.Details),
|
||||
InternalFlags: req.InternalFlags,
|
||||
ObjectTypeKey: objectTypeKey,
|
||||
TemplateId: req.TemplateId,
|
||||
|
@ -141,7 +138,7 @@ func (s *Service) CreateLinkToTheNewObject(
|
|||
|
||||
func (s *Service) ObjectToSet(id string, source []string) error {
|
||||
return cache.DoState(s, id, func(st *state.State, b basic.CommonOperations) error {
|
||||
st.SetDetail(bundle.RelationKeySetOf.String(), pbtypes.StringList(source))
|
||||
st.SetDetail(bundle.RelationKeySetOf, domain.StringList(source))
|
||||
return b.SetObjectTypesInState(st, []domain.TypeKey{bundle.TypeKeySet}, true)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ func (s *Service) getDebugObject(id string) (debugObject, error) {
|
|||
st := sb.NewState()
|
||||
root := blockbuilder.BuildAST(st.Blocks())
|
||||
marshaller := jsonpb.Marshaler{}
|
||||
detailsRaw, err := marshaller.MarshalToString(st.CombinedDetails())
|
||||
detailsRaw, err := marshaller.MarshalToString(st.CombinedDetails().ToProto())
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshal details: %w", err)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/database"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/clientspace"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func (s *Service) DeleteObjectByFullID(id domain.FullID) error {
|
||||
|
@ -56,7 +55,7 @@ func (s *Service) DeleteObjectByFullID(id domain.FullID) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sendOnRemoveEvent(s.eventSender, id.ObjectID)
|
||||
s.sendOnRemoveEvent(id.SpaceID, id.ObjectID)
|
||||
// Remove from cache
|
||||
err = spc.Remove(context.Background(), id.ObjectID)
|
||||
if err != nil {
|
||||
|
@ -72,9 +71,9 @@ func (s *Service) deleteDerivedObject(id domain.FullID, spc clientspace.Space) (
|
|||
)
|
||||
err = spc.Do(id.ObjectID, func(b smartblock.SmartBlock) error {
|
||||
st := b.NewState()
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyIsUninstalled, pbtypes.Bool(true))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyIsUninstalled, domain.Bool(true))
|
||||
if sbType == coresb.SmartBlockTypeRelation {
|
||||
relationKey = pbtypes.GetString(st.Details(), bundle.RelationKeyRelationKey.String())
|
||||
relationKey = st.Details().GetString(bundle.RelationKeyRelationKey)
|
||||
}
|
||||
return b.Apply(st)
|
||||
})
|
||||
|
@ -96,16 +95,16 @@ func (s *Service) deleteDerivedObject(id domain.FullID, spc clientspace.Space) (
|
|||
|
||||
func (s *Service) deleteRelationOptions(spaceId string, relationKey string) error {
|
||||
relationOptions, _, err := s.objectStore.SpaceIndex(spaceId).QueryObjectIds(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
RelationKey: bundle.RelationKeyLayout.String(),
|
||||
RelationKey: bundle.RelationKeyLayout,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Int64(int64(model.ObjectType_relationOption)),
|
||||
Value: domain.Int64(model.ObjectType_relationOption),
|
||||
},
|
||||
{
|
||||
RelationKey: bundle.RelationKeyRelationKey.String(),
|
||||
RelationKey: bundle.RelationKeyRelationKey,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(relationKey),
|
||||
Value: domain.String(relationKey),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -133,7 +132,7 @@ func (s *Service) OnDelete(id domain.FullID, workspaceRemove func() error) error
|
|||
err := s.DoFullId(id, func(b smartblock.SmartBlock) error {
|
||||
b.ObjectCloseAllSessions()
|
||||
st := b.NewState()
|
||||
isFavorite := pbtypes.GetBool(st.LocalDetails(), bundle.RelationKeyIsFavorite.String())
|
||||
isFavorite := st.LocalDetails().GetBool(bundle.RelationKeyIsFavorite)
|
||||
if err := s.detailsService.SetIsFavorite(id.ObjectID, isFavorite, false); err != nil {
|
||||
log.With("objectId", id).Errorf("failed to favorite object: %v", err)
|
||||
}
|
||||
|
@ -153,16 +152,10 @@ func (s *Service) OnDelete(id domain.FullID, workspaceRemove func() error) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func sendOnRemoveEvent(eventSender event.Sender, ids ...string) {
|
||||
eventSender.Broadcast(&pb.Event{
|
||||
Messages: []*pb.EventMessage{
|
||||
{
|
||||
Value: &pb.EventMessageValueOfObjectRemove{
|
||||
ObjectRemove: &pb.EventObjectRemove{
|
||||
Ids: ids,
|
||||
},
|
||||
},
|
||||
},
|
||||
func (s *Service) sendOnRemoveEvent(spaceId string, id string) {
|
||||
s.eventSender.Broadcast(event.NewEventSingleMessage(spaceId, &pb.EventMessageValueOfObjectRemove{
|
||||
ObjectRemove: &pb.EventObjectRemove{
|
||||
Ids: []string{id},
|
||||
},
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -3,44 +3,43 @@ package detailservice
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
)
|
||||
|
||||
func newStruct() *types.Struct {
|
||||
return &types.Struct{Fields: map[string]*types.Value{
|
||||
"tag": pbtypes.StringList([]string{"red", "black"}),
|
||||
"author": pbtypes.String("William Shakespeare"),
|
||||
"haters": pbtypes.StringList([]string{}),
|
||||
"year": pbtypes.Int64(1564),
|
||||
"numbers": pbtypes.IntList(8, 13, 21, 34),
|
||||
}}
|
||||
func newStruct() *domain.Details {
|
||||
return domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
"tag": domain.StringList([]string{"red", "black"}),
|
||||
"author": domain.String("William Shakespeare"),
|
||||
"haters": domain.StringList([]string{}),
|
||||
"year": domain.Int64(1564),
|
||||
"numbers": domain.Int64List([]int64{8, 13, 21, 34}),
|
||||
})
|
||||
}
|
||||
|
||||
func TestAddValueToListDetail(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
key string
|
||||
s *types.Struct
|
||||
toAdd *types.Value
|
||||
expected *types.Value
|
||||
key domain.RelationKey
|
||||
s *domain.Details
|
||||
toAdd domain.Value
|
||||
expected domain.Value
|
||||
}{
|
||||
{"string list + string list", "tag", newStruct(), pbtypes.StringList([]string{"blue", "green"}), pbtypes.StringList([]string{"red", "black", "blue", "green"})},
|
||||
{"string list + string list (intersect)", "tag", newStruct(), pbtypes.StringList([]string{"blue", "black"}), pbtypes.StringList([]string{"red", "black", "blue"})},
|
||||
{"string + string list", "author", newStruct(), pbtypes.StringList([]string{"Victor Hugo"}), pbtypes.StringList([]string{"William Shakespeare", "Victor Hugo"})},
|
||||
{"string list + string", "tag", newStruct(), pbtypes.String("orange"), pbtypes.StringList([]string{"red", "black", "orange"})},
|
||||
{"int list + int list", "numbers", newStruct(), pbtypes.IntList(55, 89), pbtypes.IntList(8, 13, 21, 34, 55, 89)},
|
||||
{"int list + int list (intersect)", "numbers", newStruct(), pbtypes.IntList(13, 8, 55), pbtypes.IntList(8, 13, 21, 34, 55)},
|
||||
{"int + int list", "year", newStruct(), pbtypes.IntList(1666, 2025), pbtypes.IntList(1564, 1666, 2025)},
|
||||
{"int list + int", "numbers", newStruct(), pbtypes.Int64(55), pbtypes.IntList(8, 13, 21, 34, 55)},
|
||||
{"string list + empty", "haters", newStruct(), pbtypes.StringList([]string{"Tomas River", "Leo Tolstoy"}), pbtypes.StringList([]string{"Tomas River", "Leo Tolstoy"})},
|
||||
{"string list + no such key", "plays", newStruct(), pbtypes.StringList([]string{"Falstaff", "Romeo and Juliet", "Macbeth"}), pbtypes.StringList([]string{"Falstaff", "Romeo and Juliet", "Macbeth"})},
|
||||
{"string list + string list", "tag", newStruct(), domain.StringList([]string{"blue", "green"}), domain.StringList([]string{"red", "black", "blue", "green"})},
|
||||
{"string list + string list (intersect)", "tag", newStruct(), domain.StringList([]string{"blue", "black"}), domain.StringList([]string{"red", "black", "blue"})},
|
||||
{"string + string list", "author", newStruct(), domain.StringList([]string{"Victor Hugo"}), domain.StringList([]string{"William Shakespeare", "Victor Hugo"})},
|
||||
{"string list + string", "tag", newStruct(), domain.String("orange"), domain.StringList([]string{"red", "black", "orange"})},
|
||||
{"int list + int list", "numbers", newStruct(), domain.Int64List([]int64{55, 89}), domain.Int64List([]int64{8, 13, 21, 34, 55, 89})},
|
||||
{"int list + int list (intersect)", "numbers", newStruct(), domain.Int64List([]int64{13, 8, 55}), domain.Int64List([]int64{8, 13, 21, 34, 55})},
|
||||
{"int + int list", "year", newStruct(), domain.Int64List([]int64{1666, 2025}), domain.Int64List([]int64{1564, 1666, 2025})},
|
||||
{"int list + int", "numbers", newStruct(), domain.Int64(55), domain.Int64List([]int64{8, 13, 21, 34, 55})},
|
||||
{"string list + empty", "haters", newStruct(), domain.StringList([]string{"Tomas River", "Leo Tolstoy"}), domain.StringList([]string{"Tomas River", "Leo Tolstoy"})},
|
||||
{"string list + no such key", "plays", newStruct(), domain.StringList([]string{"Falstaff", "Romeo and Juliet", "Macbeth"}), domain.StringList([]string{"Falstaff", "Romeo and Juliet", "Macbeth"})},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
addValueToListDetail(tc.s, tc.key, tc.toAdd)
|
||||
assert.True(t, pbtypes.Get(tc.s, tc.key).Equal(tc.expected))
|
||||
assert.True(t, tc.s.Get(tc.key).Equal(tc.expected))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -48,24 +47,23 @@ func TestAddValueToListDetail(t *testing.T) {
|
|||
func TestRemoveValueFromListDetail(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
key string
|
||||
s *types.Struct
|
||||
toRemove *types.Value
|
||||
expected *types.Value
|
||||
key domain.RelationKey
|
||||
s *domain.Details
|
||||
toRemove domain.Value
|
||||
expected domain.Value
|
||||
}{
|
||||
{"string list - string list", "tag", newStruct(), pbtypes.StringList([]string{"red", "black"}), nil},
|
||||
{"string list - string list (some are not presented)", "tag", newStruct(), pbtypes.StringList([]string{"blue", "black"}), pbtypes.StringList([]string{"red"})},
|
||||
{"string list - string", "tag", newStruct(), pbtypes.String("red"), pbtypes.StringList([]string{"black"})},
|
||||
{"string - string list", "author", newStruct(), pbtypes.StringList([]string{"William Shakespeare"}), pbtypes.StringList([]string{})},
|
||||
{"int list - int list", "numbers", newStruct(), pbtypes.IntList(13, 34), pbtypes.IntList(8, 21)},
|
||||
{"int list - int list (some are not presented)", "numbers", newStruct(), pbtypes.IntList(2020, 5), pbtypes.IntList(8, 13, 21, 34)},
|
||||
{"int - int list", "year", newStruct(), pbtypes.IntList(1380, 1564), pbtypes.IntList()},
|
||||
{"int list - int", "numbers", newStruct(), pbtypes.Int64(21), pbtypes.IntList(8, 13, 34)},
|
||||
{"empty - string list", "haters", newStruct(), pbtypes.StringList([]string{"Tomas River", "Leo Tolstoy"}), pbtypes.StringList([]string{})},
|
||||
{"string list - string list", "tag", newStruct(), domain.StringList([]string{"red", "black"}), domain.Invalid()},
|
||||
{"string list - string list (some are not presented)", "tag", newStruct(), domain.StringList([]string{"blue", "black"}), domain.StringList([]string{"red"})},
|
||||
{"string list - string", "tag", newStruct(), domain.String("red"), domain.StringList([]string{"black"})},
|
||||
{"string - string list", "author", newStruct(), domain.StringList([]string{"William Shakespeare"}), domain.StringList([]string{})},
|
||||
{"int list - int list", "numbers", newStruct(), domain.Int64List([]int64{13, 34}), domain.Int64List([]int64{8, 21})},
|
||||
{"int list - int list (some are not presented)", "numbers", newStruct(), domain.Int64List([]int64{2020, 5}), domain.Int64List([]int64{8, 13, 21, 34})},
|
||||
{"int - int list", "year", newStruct(), domain.Int64List([]int64{1380, 1564}), domain.Invalid()},
|
||||
{"int list - int", "numbers", newStruct(), domain.Int64(21), domain.Int64List([]int64{8, 13, 34})},
|
||||
{"empty - string list", "haters", newStruct(), domain.StringList([]string{"Tomas River", "Leo Tolstoy"}), domain.StringList([]string{})},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
removeValueFromListDetail(tc.s, tc.key, tc.toRemove)
|
||||
assert.True(t, pbtypes.Get(tc.s, tc.key).Equal(tc.expected))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,9 @@ import (
|
|||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
model "github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
|
||||
pb "github.com/anyproto/anytype-heart/pb"
|
||||
|
||||
session "github.com/anyproto/anytype-heart/core/session"
|
||||
|
||||
types "github.com/gogo/protobuf/types"
|
||||
)
|
||||
|
||||
// MockService is an autogenerated mock type for the Service type
|
||||
|
@ -80,7 +76,7 @@ func (_c *MockService_Init_Call) RunAndReturn(run func(*app.App) error) *MockSer
|
|||
}
|
||||
|
||||
// ListRelationsWithValue provides a mock function with given fields: spaceId, value
|
||||
func (_m *MockService) ListRelationsWithValue(spaceId string, value *types.Value) ([]*pb.RpcRelationListWithValueResponseResponseItem, error) {
|
||||
func (_m *MockService) ListRelationsWithValue(spaceId string, value domain.Value) ([]*pb.RpcRelationListWithValueResponseResponseItem, error) {
|
||||
ret := _m.Called(spaceId, value)
|
||||
|
||||
if len(ret) == 0 {
|
||||
|
@ -89,10 +85,10 @@ func (_m *MockService) ListRelationsWithValue(spaceId string, value *types.Value
|
|||
|
||||
var r0 []*pb.RpcRelationListWithValueResponseResponseItem
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(string, *types.Value) ([]*pb.RpcRelationListWithValueResponseResponseItem, error)); ok {
|
||||
if rf, ok := ret.Get(0).(func(string, domain.Value) ([]*pb.RpcRelationListWithValueResponseResponseItem, error)); ok {
|
||||
return rf(spaceId, value)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(string, *types.Value) []*pb.RpcRelationListWithValueResponseResponseItem); ok {
|
||||
if rf, ok := ret.Get(0).(func(string, domain.Value) []*pb.RpcRelationListWithValueResponseResponseItem); ok {
|
||||
r0 = rf(spaceId, value)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
|
@ -100,7 +96,7 @@ func (_m *MockService) ListRelationsWithValue(spaceId string, value *types.Value
|
|||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(string, *types.Value) error); ok {
|
||||
if rf, ok := ret.Get(1).(func(string, domain.Value) error); ok {
|
||||
r1 = rf(spaceId, value)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
|
@ -116,14 +112,14 @@ type MockService_ListRelationsWithValue_Call struct {
|
|||
|
||||
// ListRelationsWithValue is a helper method to define mock.On call
|
||||
// - spaceId string
|
||||
// - value *types.Value
|
||||
// - value domain.Value
|
||||
func (_e *MockService_Expecter) ListRelationsWithValue(spaceId interface{}, value interface{}) *MockService_ListRelationsWithValue_Call {
|
||||
return &MockService_ListRelationsWithValue_Call{Call: _e.mock.On("ListRelationsWithValue", spaceId, value)}
|
||||
}
|
||||
|
||||
func (_c *MockService_ListRelationsWithValue_Call) Run(run func(spaceId string, value *types.Value)) *MockService_ListRelationsWithValue_Call {
|
||||
func (_c *MockService_ListRelationsWithValue_Call) Run(run func(spaceId string, value domain.Value)) *MockService_ListRelationsWithValue_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(string), args[1].(*types.Value))
|
||||
run(args[0].(string), args[1].(domain.Value))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
@ -133,13 +129,13 @@ func (_c *MockService_ListRelationsWithValue_Call) Return(_a0 []*pb.RpcRelationL
|
|||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockService_ListRelationsWithValue_Call) RunAndReturn(run func(string, *types.Value) ([]*pb.RpcRelationListWithValueResponseResponseItem, error)) *MockService_ListRelationsWithValue_Call {
|
||||
func (_c *MockService_ListRelationsWithValue_Call) RunAndReturn(run func(string, domain.Value) ([]*pb.RpcRelationListWithValueResponseResponseItem, error)) *MockService_ListRelationsWithValue_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// ModifyDetails provides a mock function with given fields: objectId, modifier
|
||||
func (_m *MockService) ModifyDetails(objectId string, modifier func(*types.Struct) (*types.Struct, error)) error {
|
||||
func (_m *MockService) ModifyDetails(objectId string, modifier func(*domain.Details) (*domain.Details, error)) error {
|
||||
ret := _m.Called(objectId, modifier)
|
||||
|
||||
if len(ret) == 0 {
|
||||
|
@ -147,7 +143,7 @@ func (_m *MockService) ModifyDetails(objectId string, modifier func(*types.Struc
|
|||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, func(*types.Struct) (*types.Struct, error)) error); ok {
|
||||
if rf, ok := ret.Get(0).(func(string, func(*domain.Details) (*domain.Details, error)) error); ok {
|
||||
r0 = rf(objectId, modifier)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
|
@ -163,14 +159,14 @@ type MockService_ModifyDetails_Call struct {
|
|||
|
||||
// ModifyDetails is a helper method to define mock.On call
|
||||
// - objectId string
|
||||
// - modifier func(*types.Struct)(*types.Struct , error)
|
||||
// - modifier func(*domain.Details)(*domain.Details , error)
|
||||
func (_e *MockService_Expecter) ModifyDetails(objectId interface{}, modifier interface{}) *MockService_ModifyDetails_Call {
|
||||
return &MockService_ModifyDetails_Call{Call: _e.mock.On("ModifyDetails", objectId, modifier)}
|
||||
}
|
||||
|
||||
func (_c *MockService_ModifyDetails_Call) Run(run func(objectId string, modifier func(*types.Struct) (*types.Struct, error))) *MockService_ModifyDetails_Call {
|
||||
func (_c *MockService_ModifyDetails_Call) Run(run func(objectId string, modifier func(*domain.Details) (*domain.Details, error))) *MockService_ModifyDetails_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(string), args[1].(func(*types.Struct) (*types.Struct, error)))
|
||||
run(args[0].(string), args[1].(func(*domain.Details) (*domain.Details, error)))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
@ -180,7 +176,7 @@ func (_c *MockService_ModifyDetails_Call) Return(_a0 error) *MockService_ModifyD
|
|||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockService_ModifyDetails_Call) RunAndReturn(run func(string, func(*types.Struct) (*types.Struct, error)) error) *MockService_ModifyDetails_Call {
|
||||
func (_c *MockService_ModifyDetails_Call) RunAndReturn(run func(string, func(*domain.Details) (*domain.Details, error)) error) *MockService_ModifyDetails_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
@ -373,7 +369,7 @@ func (_c *MockService_ObjectTypeRemoveRelations_Call) RunAndReturn(run func(cont
|
|||
}
|
||||
|
||||
// SetDetails provides a mock function with given fields: ctx, objectId, details
|
||||
func (_m *MockService) SetDetails(ctx session.Context, objectId string, details []*model.Detail) error {
|
||||
func (_m *MockService) SetDetails(ctx session.Context, objectId string, details []domain.Detail) error {
|
||||
ret := _m.Called(ctx, objectId, details)
|
||||
|
||||
if len(ret) == 0 {
|
||||
|
@ -381,7 +377,7 @@ func (_m *MockService) SetDetails(ctx session.Context, objectId string, details
|
|||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(session.Context, string, []*model.Detail) error); ok {
|
||||
if rf, ok := ret.Get(0).(func(session.Context, string, []domain.Detail) error); ok {
|
||||
r0 = rf(ctx, objectId, details)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
|
@ -398,14 +394,14 @@ type MockService_SetDetails_Call struct {
|
|||
// SetDetails is a helper method to define mock.On call
|
||||
// - ctx session.Context
|
||||
// - objectId string
|
||||
// - details []*model.Detail
|
||||
// - details []domain.Detail
|
||||
func (_e *MockService_Expecter) SetDetails(ctx interface{}, objectId interface{}, details interface{}) *MockService_SetDetails_Call {
|
||||
return &MockService_SetDetails_Call{Call: _e.mock.On("SetDetails", ctx, objectId, details)}
|
||||
}
|
||||
|
||||
func (_c *MockService_SetDetails_Call) Run(run func(ctx session.Context, objectId string, details []*model.Detail)) *MockService_SetDetails_Call {
|
||||
func (_c *MockService_SetDetails_Call) Run(run func(ctx session.Context, objectId string, details []domain.Detail)) *MockService_SetDetails_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(session.Context), args[1].(string), args[2].([]*model.Detail))
|
||||
run(args[0].(session.Context), args[1].(string), args[2].([]domain.Detail))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
@ -415,13 +411,13 @@ func (_c *MockService_SetDetails_Call) Return(_a0 error) *MockService_SetDetails
|
|||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockService_SetDetails_Call) RunAndReturn(run func(session.Context, string, []*model.Detail) error) *MockService_SetDetails_Call {
|
||||
func (_c *MockService_SetDetails_Call) RunAndReturn(run func(session.Context, string, []domain.Detail) error) *MockService_SetDetails_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetDetailsAndUpdateLastUsed provides a mock function with given fields: ctx, objectId, details
|
||||
func (_m *MockService) SetDetailsAndUpdateLastUsed(ctx session.Context, objectId string, details []*model.Detail) error {
|
||||
func (_m *MockService) SetDetailsAndUpdateLastUsed(ctx session.Context, objectId string, details []domain.Detail) error {
|
||||
ret := _m.Called(ctx, objectId, details)
|
||||
|
||||
if len(ret) == 0 {
|
||||
|
@ -429,7 +425,7 @@ func (_m *MockService) SetDetailsAndUpdateLastUsed(ctx session.Context, objectId
|
|||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(session.Context, string, []*model.Detail) error); ok {
|
||||
if rf, ok := ret.Get(0).(func(session.Context, string, []domain.Detail) error); ok {
|
||||
r0 = rf(ctx, objectId, details)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
|
@ -446,14 +442,14 @@ type MockService_SetDetailsAndUpdateLastUsed_Call struct {
|
|||
// SetDetailsAndUpdateLastUsed is a helper method to define mock.On call
|
||||
// - ctx session.Context
|
||||
// - objectId string
|
||||
// - details []*model.Detail
|
||||
// - details []domain.Detail
|
||||
func (_e *MockService_Expecter) SetDetailsAndUpdateLastUsed(ctx interface{}, objectId interface{}, details interface{}) *MockService_SetDetailsAndUpdateLastUsed_Call {
|
||||
return &MockService_SetDetailsAndUpdateLastUsed_Call{Call: _e.mock.On("SetDetailsAndUpdateLastUsed", ctx, objectId, details)}
|
||||
}
|
||||
|
||||
func (_c *MockService_SetDetailsAndUpdateLastUsed_Call) Run(run func(ctx session.Context, objectId string, details []*model.Detail)) *MockService_SetDetailsAndUpdateLastUsed_Call {
|
||||
func (_c *MockService_SetDetailsAndUpdateLastUsed_Call) Run(run func(ctx session.Context, objectId string, details []domain.Detail)) *MockService_SetDetailsAndUpdateLastUsed_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(session.Context), args[1].(string), args[2].([]*model.Detail))
|
||||
run(args[0].(session.Context), args[1].(string), args[2].([]domain.Detail))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
@ -463,13 +459,13 @@ func (_c *MockService_SetDetailsAndUpdateLastUsed_Call) Return(_a0 error) *MockS
|
|||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockService_SetDetailsAndUpdateLastUsed_Call) RunAndReturn(run func(session.Context, string, []*model.Detail) error) *MockService_SetDetailsAndUpdateLastUsed_Call {
|
||||
func (_c *MockService_SetDetailsAndUpdateLastUsed_Call) RunAndReturn(run func(session.Context, string, []domain.Detail) error) *MockService_SetDetailsAndUpdateLastUsed_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetDetailsList provides a mock function with given fields: ctx, objectIds, details
|
||||
func (_m *MockService) SetDetailsList(ctx session.Context, objectIds []string, details []*model.Detail) error {
|
||||
func (_m *MockService) SetDetailsList(ctx session.Context, objectIds []string, details []domain.Detail) error {
|
||||
ret := _m.Called(ctx, objectIds, details)
|
||||
|
||||
if len(ret) == 0 {
|
||||
|
@ -477,7 +473,7 @@ func (_m *MockService) SetDetailsList(ctx session.Context, objectIds []string, d
|
|||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(session.Context, []string, []*model.Detail) error); ok {
|
||||
if rf, ok := ret.Get(0).(func(session.Context, []string, []domain.Detail) error); ok {
|
||||
r0 = rf(ctx, objectIds, details)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
|
@ -494,14 +490,14 @@ type MockService_SetDetailsList_Call struct {
|
|||
// SetDetailsList is a helper method to define mock.On call
|
||||
// - ctx session.Context
|
||||
// - objectIds []string
|
||||
// - details []*model.Detail
|
||||
// - details []domain.Detail
|
||||
func (_e *MockService_Expecter) SetDetailsList(ctx interface{}, objectIds interface{}, details interface{}) *MockService_SetDetailsList_Call {
|
||||
return &MockService_SetDetailsList_Call{Call: _e.mock.On("SetDetailsList", ctx, objectIds, details)}
|
||||
}
|
||||
|
||||
func (_c *MockService_SetDetailsList_Call) Run(run func(ctx session.Context, objectIds []string, details []*model.Detail)) *MockService_SetDetailsList_Call {
|
||||
func (_c *MockService_SetDetailsList_Call) Run(run func(ctx session.Context, objectIds []string, details []domain.Detail)) *MockService_SetDetailsList_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(session.Context), args[1].([]string), args[2].([]*model.Detail))
|
||||
run(args[0].(session.Context), args[1].([]string), args[2].([]domain.Detail))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
@ -511,7 +507,7 @@ func (_c *MockService_SetDetailsList_Call) Return(_a0 error) *MockService_SetDet
|
|||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockService_SetDetailsList_Call) RunAndReturn(run func(session.Context, []string, []*model.Detail) error) *MockService_SetDetailsList_Call {
|
||||
func (_c *MockService_SetDetailsList_Call) RunAndReturn(run func(session.Context, []string, []domain.Detail) error) *MockService_SetDetailsList_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
@ -706,7 +702,7 @@ func (_c *MockService_SetListIsFavorite_Call) RunAndReturn(run func([]string, bo
|
|||
}
|
||||
|
||||
// SetSpaceInfo provides a mock function with given fields: spaceId, details
|
||||
func (_m *MockService) SetSpaceInfo(spaceId string, details *types.Struct) error {
|
||||
func (_m *MockService) SetSpaceInfo(spaceId string, details *domain.Details) error {
|
||||
ret := _m.Called(spaceId, details)
|
||||
|
||||
if len(ret) == 0 {
|
||||
|
@ -714,7 +710,7 @@ func (_m *MockService) SetSpaceInfo(spaceId string, details *types.Struct) error
|
|||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, *types.Struct) error); ok {
|
||||
if rf, ok := ret.Get(0).(func(string, *domain.Details) error); ok {
|
||||
r0 = rf(spaceId, details)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
|
@ -730,14 +726,14 @@ type MockService_SetSpaceInfo_Call struct {
|
|||
|
||||
// SetSpaceInfo is a helper method to define mock.On call
|
||||
// - spaceId string
|
||||
// - details *types.Struct
|
||||
// - details *domain.Details
|
||||
func (_e *MockService_Expecter) SetSpaceInfo(spaceId interface{}, details interface{}) *MockService_SetSpaceInfo_Call {
|
||||
return &MockService_SetSpaceInfo_Call{Call: _e.mock.On("SetSpaceInfo", spaceId, details)}
|
||||
}
|
||||
|
||||
func (_c *MockService_SetSpaceInfo_Call) Run(run func(spaceId string, details *types.Struct)) *MockService_SetSpaceInfo_Call {
|
||||
func (_c *MockService_SetSpaceInfo_Call) Run(run func(spaceId string, details *domain.Details)) *MockService_SetSpaceInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(string), args[1].(*types.Struct))
|
||||
run(args[0].(string), args[1].(*domain.Details))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
@ -747,7 +743,7 @@ func (_c *MockService_SetSpaceInfo_Call) Return(_a0 error) *MockService_SetSpace
|
|||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockService_SetSpaceInfo_Call) RunAndReturn(run func(string, *types.Struct) error) *MockService_SetSpaceInfo_Call {
|
||||
func (_c *MockService_SetSpaceInfo_Call) RunAndReturn(run func(string, *domain.Details) error) *MockService_SetSpaceInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
|
@ -21,7 +20,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/database"
|
||||
"github.com/anyproto/anytype-heart/space/spacecore/typeprovider"
|
||||
"github.com/anyproto/anytype-heart/util/dateutil"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
timeutil "github.com/anyproto/anytype-heart/util/time"
|
||||
)
|
||||
|
@ -34,7 +32,7 @@ func (s *service) ObjectTypeAddRelations(ctx context.Context, objectTypeId strin
|
|||
}
|
||||
return cache.Do(s.objectGetter, objectTypeId, func(b smartblock.SmartBlock) error {
|
||||
st := b.NewState()
|
||||
list := pbtypes.GetStringList(st.Details(), bundle.RelationKeyRecommendedRelations.String())
|
||||
list := st.Details().GetStringList(bundle.RelationKeyRecommendedRelations)
|
||||
for _, relKey := range relationKeys {
|
||||
relId, err := b.Space().GetRelationIdByKey(ctx, relKey)
|
||||
if err != nil {
|
||||
|
@ -44,7 +42,7 @@ func (s *service) ObjectTypeAddRelations(ctx context.Context, objectTypeId strin
|
|||
list = append(list, relId)
|
||||
}
|
||||
}
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyRecommendedRelations, pbtypes.StringList(list))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyRecommendedRelations, domain.StringList(list))
|
||||
return b.Apply(st)
|
||||
})
|
||||
}
|
||||
|
@ -55,7 +53,7 @@ func (s *service) ObjectTypeRemoveRelations(ctx context.Context, objectTypeId st
|
|||
}
|
||||
return cache.Do(s.objectGetter, objectTypeId, func(b smartblock.SmartBlock) error {
|
||||
st := b.NewState()
|
||||
list := pbtypes.GetStringList(st.Details(), bundle.RelationKeyRecommendedRelations.String())
|
||||
list := st.Details().GetStringList(bundle.RelationKeyRecommendedRelations)
|
||||
for _, relKey := range relationKeys {
|
||||
relId, err := b.Space().GetRelationIdByKey(ctx, relKey)
|
||||
if err != nil {
|
||||
|
@ -63,28 +61,30 @@ func (s *service) ObjectTypeRemoveRelations(ctx context.Context, objectTypeId st
|
|||
}
|
||||
list = slice.RemoveMut(list, relId)
|
||||
}
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyRecommendedRelations, pbtypes.StringList(list))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyRecommendedRelations, domain.StringList(list))
|
||||
return b.Apply(st)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *service) ListRelationsWithValue(spaceId string, value *types.Value) ([]*pb.RpcRelationListWithValueResponseResponseItem, error) {
|
||||
func (s *service) ListRelationsWithValue(spaceId string, value domain.Value) ([]*pb.RpcRelationListWithValueResponseResponseItem, error) {
|
||||
var (
|
||||
countersByKeys = make(map[string]int64)
|
||||
countersByKeys = make(map[domain.RelationKey]int64)
|
||||
detailHandlesValue = generateFilter(value)
|
||||
)
|
||||
|
||||
err := s.store.SpaceIndex(spaceId).QueryIterate(database.Query{Filters: nil}, func(details *types.Struct) {
|
||||
for key, valueToCheck := range details.Fields {
|
||||
if detailHandlesValue(valueToCheck) {
|
||||
if counter, ok := countersByKeys[key]; ok {
|
||||
countersByKeys[key] = counter + 1
|
||||
} else {
|
||||
countersByKeys[key] = 1
|
||||
err := s.store.SpaceIndex(spaceId).QueryIterate(
|
||||
database.Query{Filters: nil},
|
||||
func(details *domain.Details) {
|
||||
for key, valueToCheck := range details.Iterate() {
|
||||
if detailHandlesValue(valueToCheck) {
|
||||
if counter, ok := countersByKeys[key]; ok {
|
||||
countersByKeys[key] = counter + 1
|
||||
} else {
|
||||
countersByKeys[key] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query objects: %w", err)
|
||||
|
@ -92,10 +92,10 @@ func (s *service) ListRelationsWithValue(spaceId string, value *types.Value) ([]
|
|||
|
||||
keys := maps.Keys(countersByKeys)
|
||||
sort.Slice(keys, func(i, j int) bool {
|
||||
if keys[i] == bundle.RelationKeyMentions.String() {
|
||||
if keys[i] == bundle.RelationKeyMentions {
|
||||
return true
|
||||
}
|
||||
if keys[j] == bundle.RelationKeyMentions.String() {
|
||||
if keys[j] == bundle.RelationKeyMentions {
|
||||
return false
|
||||
}
|
||||
return keys[i] < keys[j]
|
||||
|
@ -104,7 +104,7 @@ func (s *service) ListRelationsWithValue(spaceId string, value *types.Value) ([]
|
|||
list := make([]*pb.RpcRelationListWithValueResponseResponseItem, len(keys))
|
||||
for i, key := range keys {
|
||||
list[i] = &pb.RpcRelationListWithValueResponseResponseItem{
|
||||
RelationKey: key,
|
||||
RelationKey: string(key),
|
||||
Counter: countersByKeys[key],
|
||||
}
|
||||
}
|
||||
|
@ -112,10 +112,10 @@ func (s *service) ListRelationsWithValue(spaceId string, value *types.Value) ([]
|
|||
return list, nil
|
||||
}
|
||||
|
||||
func generateFilter(value *types.Value) func(v *types.Value) bool {
|
||||
equalOrHasFilter := func(v *types.Value) bool {
|
||||
if list := v.GetListValue(); list != nil {
|
||||
for _, element := range list.Values {
|
||||
func generateFilter(value domain.Value) func(v domain.Value) bool {
|
||||
equalOrHasFilter := func(v domain.Value) bool {
|
||||
if list, ok := v.TryListValues(); ok {
|
||||
for _, element := range list {
|
||||
if element.Equal(value) {
|
||||
return true
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ func generateFilter(value *types.Value) func(v *types.Value) bool {
|
|||
return v.Equal(value)
|
||||
}
|
||||
|
||||
stringValue := value.GetStringValue()
|
||||
stringValue := value.String()
|
||||
if stringValue == "" {
|
||||
return equalOrHasFilter
|
||||
}
|
||||
|
@ -158,22 +158,21 @@ func generateFilter(value *types.Value) func(v *types.Value) bool {
|
|||
// - for relations with number format it checks timestamp value is between timestamps of this day midnights
|
||||
// - for relations carrying string list it checks if some of the strings has day prefix, e.g.
|
||||
// if _date_2023-12-12-08-30-50Z-0200 is queried, then all relations with prefix _date_2023-12-12 will be returned
|
||||
return func(v *types.Value) bool {
|
||||
numberValue := int64(v.GetNumberValue())
|
||||
return func(v domain.Value) bool {
|
||||
numberValue := v.Int64()
|
||||
if numberValue >= startTimestamp && numberValue < endTimestamp {
|
||||
return true
|
||||
}
|
||||
|
||||
if list := v.GetListValue(); list != nil {
|
||||
for _, element := range list.Values {
|
||||
if element.Equal(value) {
|
||||
return true
|
||||
}
|
||||
if strings.HasPrefix(element.GetStringValue(), shortId) {
|
||||
return true
|
||||
}
|
||||
for _, element := range v.WrapToList() {
|
||||
if element.Equal(value) {
|
||||
return true
|
||||
}
|
||||
if strings.HasPrefix(element.String(), shortId) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return v.Equal(value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
|
@ -18,16 +17,15 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/dateutil"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func relationObject(key domain.RelationKey, format model.RelationFormat) objectstore.TestObject {
|
||||
return objectstore.TestObject{
|
||||
bundle.RelationKeyId: pbtypes.String(key.URL()),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyLayout: pbtypes.Float64(float64(model.ObjectType_relation)),
|
||||
bundle.RelationKeyRelationKey: pbtypes.String(key.String()),
|
||||
bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(format)),
|
||||
bundle.RelationKeyId: domain.String(key.URL()),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyLayout: domain.Float64(float64(model.ObjectType_relation)),
|
||||
bundle.RelationKeyRelationKey: domain.String(key.String()),
|
||||
bundle.RelationKeyRelationFormat: domain.Int64(int64(format)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,33 +45,33 @@ func TestService_ListRelationsWithValue(t *testing.T) {
|
|||
relationObject("daysTillSummer", model.RelationFormat_number),
|
||||
relationObject(bundle.RelationKeyCoverX, model.RelationFormat_number),
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("obj1"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyCreatedDate: pbtypes.Int64(now.Add(-5 * time.Minute).Unix()),
|
||||
bundle.RelationKeyAddedDate: pbtypes.Int64(now.Add(-3 * time.Minute).Unix()),
|
||||
bundle.RelationKeyLastModifiedDate: pbtypes.Int64(now.Add(-1 * time.Minute).Unix()),
|
||||
bundle.RelationKeyIsFavorite: pbtypes.Bool(true),
|
||||
"daysTillSummer": pbtypes.Int64(300),
|
||||
bundle.RelationKeyLinks: pbtypes.StringList([]string{"obj2", "obj3", dateutil.NewDateObject(now.Add(-30*time.Minute), true).Id()}),
|
||||
bundle.RelationKeyId: domain.String("obj1"),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyCreatedDate: domain.Int64(now.Add(-5 * time.Minute).Unix()),
|
||||
bundle.RelationKeyAddedDate: domain.Int64(now.Add(-3 * time.Minute).Unix()),
|
||||
bundle.RelationKeyLastModifiedDate: domain.Int64(now.Add(-1 * time.Minute).Unix()),
|
||||
bundle.RelationKeyIsFavorite: domain.Bool(true),
|
||||
"daysTillSummer": domain.Int64(300),
|
||||
bundle.RelationKeyLinks: domain.StringList([]string{"obj2", "obj3", dateutil.NewDateObject(now.Add(-30*time.Minute), true).Id()}),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("obj2"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyName: pbtypes.String(dateutil.NewDateObject(now, true).Id()),
|
||||
bundle.RelationKeyCreatedDate: pbtypes.Int64(now.Add(-24*time.Hour - 5*time.Minute).Unix()),
|
||||
bundle.RelationKeyAddedDate: pbtypes.Int64(now.Add(-24*time.Hour - 3*time.Minute).Unix()),
|
||||
bundle.RelationKeyLastModifiedDate: pbtypes.Int64(now.Add(-1 * time.Minute).Unix()),
|
||||
bundle.RelationKeyCoverX: pbtypes.Int64(300),
|
||||
bundle.RelationKeyId: domain.String("obj2"),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyName: domain.String(dateutil.NewDateObject(now, true).Id()),
|
||||
bundle.RelationKeyCreatedDate: domain.Int64(now.Add(-24*time.Hour - 5*time.Minute).Unix()),
|
||||
bundle.RelationKeyAddedDate: domain.Int64(now.Add(-24*time.Hour - 3*time.Minute).Unix()),
|
||||
bundle.RelationKeyLastModifiedDate: domain.Int64(now.Add(-1 * time.Minute).Unix()),
|
||||
bundle.RelationKeyCoverX: domain.Int64(300),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("obj3"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyIsHidden: pbtypes.Bool(true),
|
||||
bundle.RelationKeyCreatedDate: pbtypes.Int64(now.Add(-3 * time.Minute).Unix()),
|
||||
bundle.RelationKeyLastModifiedDate: pbtypes.Int64(now.Unix()),
|
||||
bundle.RelationKeyIsFavorite: pbtypes.Bool(true),
|
||||
bundle.RelationKeyCoverX: pbtypes.Int64(300),
|
||||
bundle.RelationKeyMentions: pbtypes.StringList([]string{dateutil.NewDateObject(now, true).Id(), dateutil.NewDateObject(now.Add(-24*time.Hour), true).Id()}),
|
||||
bundle.RelationKeyId: domain.String("obj3"),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyIsHidden: domain.Bool(true),
|
||||
bundle.RelationKeyCreatedDate: domain.Int64(now.Add(-3 * time.Minute).Unix()),
|
||||
bundle.RelationKeyLastModifiedDate: domain.Int64(now.Unix()),
|
||||
bundle.RelationKeyIsFavorite: domain.Bool(true),
|
||||
bundle.RelationKeyCoverX: domain.Int64(300),
|
||||
bundle.RelationKeyMentions: domain.StringList([]string{dateutil.NewDateObject(now, true).Id(), dateutil.NewDateObject(now.Add(-24*time.Hour), true).Id()}),
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -81,12 +79,12 @@ func TestService_ListRelationsWithValue(t *testing.T) {
|
|||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
value *types.Value
|
||||
value domain.Value
|
||||
expectedList []*pb.RpcRelationListWithValueResponseResponseItem
|
||||
}{
|
||||
{
|
||||
"date object - today",
|
||||
pbtypes.String(dateutil.NewDateObject(now, true).Id()),
|
||||
domain.String(dateutil.NewDateObject(now, true).Id()),
|
||||
[]*pb.RpcRelationListWithValueResponseResponseItem{
|
||||
{bundle.RelationKeyMentions.String(), 1},
|
||||
{bundle.RelationKeyAddedDate.String(), 1},
|
||||
|
@ -98,7 +96,7 @@ func TestService_ListRelationsWithValue(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"date object - yesterday",
|
||||
pbtypes.String(dateutil.NewDateObject(now.Add(-24*time.Hour), true).Id()),
|
||||
domain.String(dateutil.NewDateObject(now.Add(-24*time.Hour), true).Id()),
|
||||
[]*pb.RpcRelationListWithValueResponseResponseItem{
|
||||
{bundle.RelationKeyMentions.String(), 1},
|
||||
{bundle.RelationKeyAddedDate.String(), 1},
|
||||
|
@ -107,7 +105,7 @@ func TestService_ListRelationsWithValue(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"number",
|
||||
pbtypes.Int64(300),
|
||||
domain.Int64(300),
|
||||
[]*pb.RpcRelationListWithValueResponseResponseItem{
|
||||
{bundle.RelationKeyCoverX.String(), 2},
|
||||
{"daysTillSummer", 1},
|
||||
|
@ -115,7 +113,7 @@ func TestService_ListRelationsWithValue(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"bool",
|
||||
pbtypes.Bool(true),
|
||||
domain.Bool(true),
|
||||
[]*pb.RpcRelationListWithValueResponseResponseItem{
|
||||
{bundle.RelationKeyIsFavorite.String(), 2},
|
||||
{bundle.RelationKeyIsHidden.String(), 1},
|
||||
|
@ -123,7 +121,7 @@ func TestService_ListRelationsWithValue(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"string list",
|
||||
pbtypes.StringList([]string{"obj2", "obj3", dateutil.NewDateObject(now.Add(-30*time.Minute), true).Id()}),
|
||||
domain.StringList([]string{"obj2", "obj3", dateutil.NewDateObject(now.Add(-30*time.Minute), true).Id()}),
|
||||
[]*pb.RpcRelationListWithValueResponseResponseItem{
|
||||
{bundle.RelationKeyLinks.String(), 1},
|
||||
},
|
||||
|
@ -159,7 +157,7 @@ func TestService_ObjectTypeAddRelations(t *testing.T) {
|
|||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []string{bundle.RelationKeyAssignee.URL(), bundle.RelationKeyDone.URL()},
|
||||
pbtypes.GetStringList(sb.Details(), bundle.RelationKeyRecommendedRelations.String()))
|
||||
sb.Details().GetStringList(bundle.RelationKeyRecommendedRelations))
|
||||
})
|
||||
|
||||
t.Run("editing of bundled types is prohibited", func(t *testing.T) {
|
||||
|
@ -183,14 +181,14 @@ func TestService_ObjectTypeRemoveRelations(t *testing.T) {
|
|||
fx := newFixture(t)
|
||||
sb := smarttest.New(bundle.TypeKeyTask.URL())
|
||||
sb.SetSpace(fx.space)
|
||||
sb.Doc.(*state.State).SetDetails(&types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyRecommendedRelations.String(): pbtypes.StringList([]string{
|
||||
sb.Doc.(*state.State).SetDetails(domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyRecommendedRelations: domain.StringList([]string{
|
||||
bundle.RelationKeyAssignee.URL(),
|
||||
bundle.RelationKeyIsFavorite.URL(),
|
||||
bundle.RelationKeyDone.URL(),
|
||||
bundle.RelationKeyLinkedProjects.URL(),
|
||||
}),
|
||||
}})
|
||||
}))
|
||||
fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(ctx context.Context, objectId string) (smartblock.SmartBlock, error) {
|
||||
assert.Equal(t, bundle.TypeKeyTask.URL(), objectId)
|
||||
return sb, nil
|
||||
|
@ -207,7 +205,7 @@ func TestService_ObjectTypeRemoveRelations(t *testing.T) {
|
|||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []string{bundle.RelationKeyIsFavorite.URL(), bundle.RelationKeyLinkedProjects.URL()},
|
||||
pbtypes.GetStringList(sb.Details(), bundle.RelationKeyRecommendedRelations.String()))
|
||||
sb.Details().GetStringList(bundle.RelationKeyRecommendedRelations))
|
||||
})
|
||||
|
||||
t.Run("editing of bundled types is prohibited", func(t *testing.T) {
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/app/logger"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/samber/lo"
|
||||
"go.uber.org/zap"
|
||||
|
||||
|
@ -19,7 +18,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
|
@ -32,18 +30,18 @@ var log = logger.NewNamed(CName)
|
|||
type Service interface {
|
||||
app.Component
|
||||
|
||||
SetDetails(ctx session.Context, objectId string, details []*model.Detail) error
|
||||
SetDetailsAndUpdateLastUsed(ctx session.Context, objectId string, details []*model.Detail) error
|
||||
SetDetailsList(ctx session.Context, objectIds []string, details []*model.Detail) error
|
||||
ModifyDetails(objectId string, modifier func(current *types.Struct) (*types.Struct, error)) error
|
||||
SetDetails(ctx session.Context, objectId string, details []domain.Detail) error
|
||||
SetDetailsAndUpdateLastUsed(ctx session.Context, objectId string, details []domain.Detail) error
|
||||
SetDetailsList(ctx session.Context, objectIds []string, details []domain.Detail) error
|
||||
ModifyDetails(objectId string, modifier func(current *domain.Details) (*domain.Details, error)) error
|
||||
ModifyDetailsList(req *pb.RpcObjectListModifyDetailValuesRequest) error
|
||||
|
||||
ObjectTypeAddRelations(ctx context.Context, objectTypeId string, relationKeys []domain.RelationKey) error
|
||||
ObjectTypeRemoveRelations(ctx context.Context, objectTypeId string, relationKeys []domain.RelationKey) error
|
||||
|
||||
ListRelationsWithValue(spaceId string, value *types.Value) ([]*pb.RpcRelationListWithValueResponseResponseItem, error)
|
||||
ListRelationsWithValue(spaceId string, value domain.Value) ([]*pb.RpcRelationListWithValueResponseResponseItem, error)
|
||||
|
||||
SetSpaceInfo(spaceId string, details *types.Struct) error
|
||||
SetSpaceInfo(spaceId string, details *domain.Details) error
|
||||
SetWorkspaceDashboardId(ctx session.Context, workspaceId string, id string) (setId string, err error)
|
||||
|
||||
SetIsFavorite(objectId string, isFavorite, createWidget bool) error
|
||||
|
@ -77,19 +75,19 @@ func (s *service) Name() string {
|
|||
return CName
|
||||
}
|
||||
|
||||
func (s *service) SetDetails(ctx session.Context, objectId string, details []*model.Detail) (err error) {
|
||||
func (s *service) SetDetails(ctx session.Context, objectId string, details []domain.Detail) (err error) {
|
||||
return cache.Do(s.objectGetter, objectId, func(b basic.DetailsSettable) error {
|
||||
return b.SetDetails(ctx, details, true)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *service) SetDetailsAndUpdateLastUsed(ctx session.Context, objectId string, details []*model.Detail) (err error) {
|
||||
func (s *service) SetDetailsAndUpdateLastUsed(ctx session.Context, objectId string, details []domain.Detail) (err error) {
|
||||
return cache.Do(s.objectGetter, objectId, func(b basic.DetailsSettable) error {
|
||||
return b.SetDetailsAndUpdateLastUsed(ctx, details, true)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *service) SetDetailsList(ctx session.Context, objectIds []string, details []*model.Detail) (err error) {
|
||||
func (s *service) SetDetailsList(ctx session.Context, objectIds []string, details []domain.Detail) (err error) {
|
||||
var (
|
||||
resultError error
|
||||
anySucceed bool
|
||||
|
@ -116,13 +114,13 @@ func (s *service) SetDetailsList(ctx session.Context, objectIds []string, detail
|
|||
}
|
||||
|
||||
// ModifyDetails performs details get and update under the sb lock to make sure no modifications are done in the middle
|
||||
func (s *service) ModifyDetails(objectId string, modifier func(current *types.Struct) (*types.Struct, error)) (err error) {
|
||||
func (s *service) ModifyDetails(objectId string, modifier func(current *domain.Details) (*domain.Details, error)) (err error) {
|
||||
return cache.Do(s.objectGetter, objectId, func(du basic.DetailsUpdatable) error {
|
||||
return du.UpdateDetails(modifier)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *service) ModifyDetailsAndUpdateLastUsed(objectId string, modifier func(current *types.Struct) (*types.Struct, error)) (err error) {
|
||||
func (s *service) ModifyDetailsAndUpdateLastUsed(objectId string, modifier func(current *domain.Details) (*domain.Details, error)) (err error) {
|
||||
return cache.Do(s.objectGetter, objectId, func(du basic.DetailsUpdatable) error {
|
||||
return du.UpdateDetailsAndLastUsed(modifier)
|
||||
})
|
||||
|
@ -135,15 +133,15 @@ func (s *service) ModifyDetailsList(req *pb.RpcObjectListModifyDetailValuesReque
|
|||
if i == 0 {
|
||||
modifyDetailsFunc = s.ModifyDetailsAndUpdateLastUsed
|
||||
}
|
||||
err := modifyDetailsFunc(objectId, func(current *types.Struct) (*types.Struct, error) {
|
||||
err := modifyDetailsFunc(objectId, func(current *domain.Details) (*domain.Details, error) {
|
||||
for _, op := range req.Operations {
|
||||
if !pbtypes.IsNullValue(op.Set) {
|
||||
// Set operation has higher priority than Add and Remove, because it modifies full value
|
||||
current.Fields[op.RelationKey] = op.Set
|
||||
current.Set(domain.RelationKey(op.RelationKey), domain.ValueFromProto(op.Set))
|
||||
continue
|
||||
}
|
||||
addValueToListDetail(current, op.RelationKey, op.Add)
|
||||
removeValueFromListDetail(current, op.RelationKey, op.Remove)
|
||||
addValueToListDetail(current, domain.RelationKey(op.RelationKey), domain.ValueFromProto(op.Add))
|
||||
removeValueFromListDetail(current, domain.RelationKey(op.RelationKey), domain.ValueFromProto(op.Remove))
|
||||
}
|
||||
return current, nil
|
||||
})
|
||||
|
@ -163,44 +161,51 @@ func (s *service) ModifyDetailsList(req *pb.RpcObjectListModifyDetailValuesReque
|
|||
}
|
||||
|
||||
// addValueToListDetail adds values to int lists and string lists
|
||||
func addValueToListDetail(s *types.Struct, key string, v *types.Value) {
|
||||
if pbtypes.IsStructEmpty(s) || v == nil {
|
||||
func addValueToListDetail(s *domain.Details, key domain.RelationKey, v domain.Value) {
|
||||
if s.Len() == 0 || v.IsNull() {
|
||||
return
|
||||
}
|
||||
toAdd := pbtypes.GetList(v)
|
||||
oldValues := pbtypes.GetValueList(s, key)
|
||||
newValues := slice.MergeUniqBy(oldValues, toAdd, func(this *types.Value, that *types.Value) bool {
|
||||
toAdd := v.WrapToList()
|
||||
oldValues := s.Get(key).WrapToList()
|
||||
newValues := slice.MergeUniqBy(oldValues, toAdd, func(this domain.Value, that domain.Value) bool {
|
||||
return this.Equal(that)
|
||||
})
|
||||
s.Fields[key] = &types.Value{
|
||||
Kind: &types.Value_ListValue{ListValue: &types.ListValue{Values: newValues}},
|
||||
}
|
||||
s.Set(key, domain.ValueList(newValues))
|
||||
}
|
||||
|
||||
// removeValueFromListDetail removes values from int lists and string lists
|
||||
func removeValueFromListDetail(s *types.Struct, key string, v *types.Value) {
|
||||
if pbtypes.IsStructEmpty(s) || v == nil {
|
||||
func removeValueFromListDetail(s *domain.Details, key domain.RelationKey, v domain.Value) {
|
||||
if s.Len() == 0 || v.IsNull() {
|
||||
return
|
||||
}
|
||||
value := pbtypes.Get(s, key)
|
||||
if value == nil {
|
||||
value, ok := s.TryGet(key)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if value.Equal(v) {
|
||||
delete(s.Fields, key)
|
||||
s.Delete(key)
|
||||
return
|
||||
}
|
||||
oldValues := pbtypes.GetList(value)
|
||||
oldValues := value.WrapToList()
|
||||
if len(oldValues) == 0 {
|
||||
return
|
||||
}
|
||||
toDelete := pbtypes.GetList(v)
|
||||
newValues := lo.Filter(oldValues, func(oldValue *types.Value, _ int) bool {
|
||||
return !slices.ContainsFunc(toDelete, func(valueToDelete *types.Value) bool {
|
||||
toDelete := v.WrapToList()
|
||||
newValues := lo.Filter(oldValues, func(oldValue domain.Value, _ int) bool {
|
||||
return !slices.ContainsFunc(toDelete, func(valueToDelete domain.Value) bool {
|
||||
return oldValue.Equal(valueToDelete)
|
||||
})
|
||||
})
|
||||
s.Fields[key] = &types.Value{
|
||||
Kind: &types.Value_ListValue{ListValue: &types.ListValue{Values: newValues}},
|
||||
|
||||
if len(newValues) == 0 {
|
||||
if value.IsStringList() {
|
||||
s.Set(key, domain.StringList(nil))
|
||||
} else {
|
||||
s.Set(key, domain.Float64List(nil))
|
||||
}
|
||||
} else {
|
||||
s.Set(key, domain.ValueList(newValues))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -19,6 +18,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/restriction"
|
||||
"github.com/anyproto/anytype-heart/core/block/restriction/mock_restriction"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
|
@ -73,10 +73,10 @@ func newFixture(t *testing.T) *fixture {
|
|||
}
|
||||
|
||||
func TestService_SetDetailsList(t *testing.T) {
|
||||
details := []*model.Detail{
|
||||
{Key: bundle.RelationKeyAssignee.String(), Value: pbtypes.String("Mark Twain")},
|
||||
{Key: bundle.RelationKeyDone.String(), Value: pbtypes.Bool(true)},
|
||||
{Key: bundle.RelationKeyLinkedProjects.String(), Value: pbtypes.StringList([]string{"important", "urgent"})},
|
||||
details := []domain.Detail{
|
||||
{Key: bundle.RelationKeyAssignee, Value: domain.String("Mark Twain")},
|
||||
{Key: bundle.RelationKeyDone, Value: domain.Bool(true)},
|
||||
{Key: bundle.RelationKeyLinkedProjects, Value: domain.StringList([]string{"important", "urgent"})},
|
||||
}
|
||||
|
||||
t.Run("lastUsed is updated once", func(t *testing.T) {
|
||||
|
@ -109,9 +109,9 @@ func TestService_SetDetailsList(t *testing.T) {
|
|||
assert.Len(t, objects["obj2"].Results.LastUsedUpdates, 0)
|
||||
assert.Len(t, objects["obj3"].Results.LastUsedUpdates, 0)
|
||||
|
||||
assert.Equal(t, "Mark Twain", pbtypes.GetString(objects["obj1"].NewState().Details(), bundle.RelationKeyAssignee.String()))
|
||||
assert.True(t, pbtypes.GetBool(objects["obj2"].NewState().Details(), bundle.RelationKeyDone.String()))
|
||||
assert.Equal(t, []string{"important", "urgent"}, pbtypes.GetStringList(objects["obj3"].NewState().Details(), bundle.RelationKeyLinkedProjects.String()))
|
||||
assert.Equal(t, "Mark Twain", objects["obj1"].NewState().Details().GetString(bundle.RelationKeyAssignee))
|
||||
assert.True(t, objects["obj2"].NewState().Details().GetBool(bundle.RelationKeyDone))
|
||||
assert.Equal(t, []string{"important", "urgent"}, objects["obj3"].NewState().Details().GetStringList(bundle.RelationKeyLinkedProjects))
|
||||
})
|
||||
|
||||
t.Run("some updates failed", func(t *testing.T) {
|
||||
|
@ -148,9 +148,9 @@ func TestService_SetDetailsList(t *testing.T) {
|
|||
|
||||
func TestService_ModifyDetailsList(t *testing.T) {
|
||||
ops := []*pb.RpcObjectListModifyDetailValuesRequestOperation{
|
||||
{RelationKey: bundle.RelationKeyName.String(), Set: pbtypes.String("My favorite page")},
|
||||
{RelationKey: bundle.RelationKeyLinks.String(), Add: pbtypes.String("some link")},
|
||||
{RelationKey: bundle.RelationKeyDone.String(), Set: pbtypes.Bool(true)},
|
||||
{RelationKey: bundle.RelationKeyName.String(), Set: domain.String("My favorite page").ToProto()},
|
||||
{RelationKey: bundle.RelationKeyLinks.String(), Add: domain.String("some link").ToProto()},
|
||||
{RelationKey: bundle.RelationKeyDone.String(), Set: domain.Bool(true).ToProto()},
|
||||
}
|
||||
|
||||
t.Run("lastUsed is updated once", func(t *testing.T) {
|
||||
|
@ -222,7 +222,7 @@ func TestService_ModifyDetailsList(t *testing.T) {
|
|||
// given
|
||||
fx := newFixture(t)
|
||||
object := smarttest.New("obj1")
|
||||
err := object.SetDetails(nil, []*model.Detail{{Key: bundle.RelationKeyDone.String(), Value: pbtypes.Bool(true)}}, false)
|
||||
err := object.SetDetails(nil, []domain.Detail{{Key: bundle.RelationKeyDone, Value: domain.Bool(true)}}, false)
|
||||
require.NoError(t, err)
|
||||
fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) {
|
||||
return object, nil
|
||||
|
@ -240,18 +240,18 @@ func TestService_ModifyDetailsList(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, pbtypes.GetBool(object.Details(), bundle.RelationKeyDone.String()))
|
||||
assert.False(t, object.Details().GetBool(bundle.RelationKeyDone))
|
||||
})
|
||||
}
|
||||
|
||||
func TestService_SetSpaceInfo(t *testing.T) {
|
||||
var (
|
||||
wsObjectId = "workspace"
|
||||
details = &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String("My space"),
|
||||
bundle.RelationKeyIconOption.String(): pbtypes.Int64(5),
|
||||
bundle.RelationKeyIconImage.String(): pbtypes.String("kitten.jpg"),
|
||||
}}
|
||||
details = domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyName: domain.String("My space"),
|
||||
bundle.RelationKeyIconOption: domain.Int64(5),
|
||||
bundle.RelationKeyIconImage: domain.String("kitten.jpg"),
|
||||
})
|
||||
)
|
||||
|
||||
t.Run("no error", func(t *testing.T) {
|
||||
|
@ -269,9 +269,9 @@ func TestService_SetSpaceInfo(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "My space", pbtypes.GetString(ws.NewState().Details(), bundle.RelationKeyName.String()))
|
||||
assert.Equal(t, int64(5), pbtypes.GetInt64(ws.NewState().Details(), bundle.RelationKeyIconOption.String()))
|
||||
assert.Equal(t, "kitten.jpg", pbtypes.GetString(ws.NewState().Details(), bundle.RelationKeyIconImage.String()))
|
||||
assert.Equal(t, "My space", ws.NewState().Details().GetString(bundle.RelationKeyName))
|
||||
assert.Equal(t, int64(5), ws.NewState().Details().GetInt64(bundle.RelationKeyIconOption))
|
||||
assert.Equal(t, "kitten.jpg", ws.NewState().Details().GetString(bundle.RelationKeyIconImage))
|
||||
})
|
||||
|
||||
t.Run("error on details setting", func(t *testing.T) {
|
||||
|
@ -317,7 +317,7 @@ func TestService_SetWorkspaceDashboardId(t *testing.T) {
|
|||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, dashboardId, setId)
|
||||
assert.Equal(t, dashboardId, pbtypes.GetString(sb.NewState().Details(), bundle.RelationKeySpaceDashboardId.String()))
|
||||
assert.Equal(t, []string{dashboardId}, sb.NewState().Details().GetStringList(bundle.RelationKeySpaceDashboardId))
|
||||
})
|
||||
|
||||
t.Run("error if wrong smartblock type", func(t *testing.T) {
|
||||
|
@ -346,9 +346,9 @@ func TestService_SetWorkspaceDashboardId(t *testing.T) {
|
|||
func TestService_SetListIsFavorite(t *testing.T) {
|
||||
var (
|
||||
objects = []objectstore.TestObject{
|
||||
{bundle.RelationKeyId: pbtypes.String("obj1"), bundle.RelationKeySpaceId: pbtypes.String(spaceId)},
|
||||
{bundle.RelationKeyId: pbtypes.String("obj2"), bundle.RelationKeySpaceId: pbtypes.String(spaceId)},
|
||||
{bundle.RelationKeyId: pbtypes.String("obj3"), bundle.RelationKeySpaceId: pbtypes.String(spaceId)},
|
||||
{bundle.RelationKeyId: domain.String("obj1"), bundle.RelationKeySpaceId: domain.String(spaceId)},
|
||||
{bundle.RelationKeyId: domain.String("obj2"), bundle.RelationKeySpaceId: domain.String(spaceId)},
|
||||
{bundle.RelationKeyId: domain.String("obj3"), bundle.RelationKeySpaceId: domain.String(spaceId)},
|
||||
}
|
||||
homeId = "home"
|
||||
widgetId = "widget"
|
||||
|
@ -467,7 +467,7 @@ func TestService_SetListIsFavorite(t *testing.T) {
|
|||
func TestService_SetIsArchived(t *testing.T) {
|
||||
var (
|
||||
objects = []objectstore.TestObject{
|
||||
{bundle.RelationKeyId: pbtypes.String("obj1"), bundle.RelationKeySpaceId: pbtypes.String(spaceId)},
|
||||
{bundle.RelationKeyId: domain.String("obj1"), bundle.RelationKeySpaceId: domain.String(spaceId)},
|
||||
}
|
||||
binId = "bin"
|
||||
)
|
||||
|
@ -522,9 +522,9 @@ func TestService_SetIsArchived(t *testing.T) {
|
|||
func TestService_SetListIsArchived(t *testing.T) {
|
||||
var (
|
||||
objects = []objectstore.TestObject{
|
||||
{bundle.RelationKeyId: pbtypes.String("obj1"), bundle.RelationKeySpaceId: pbtypes.String(spaceId)},
|
||||
{bundle.RelationKeyId: pbtypes.String("obj2"), bundle.RelationKeySpaceId: pbtypes.String(spaceId)},
|
||||
{bundle.RelationKeyId: pbtypes.String("obj3"), bundle.RelationKeySpaceId: pbtypes.String(spaceId)},
|
||||
{bundle.RelationKeyId: domain.String("obj1"), bundle.RelationKeySpaceId: domain.String(spaceId)},
|
||||
{bundle.RelationKeyId: domain.String("obj2"), bundle.RelationKeySpaceId: domain.String(spaceId)},
|
||||
{bundle.RelationKeyId: domain.String("obj3"), bundle.RelationKeySpaceId: domain.String(spaceId)},
|
||||
}
|
||||
binId = "bin"
|
||||
)
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/cache"
|
||||
|
@ -15,18 +14,18 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/widget"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
var ErrUnexpectedBlockType = errors.New("unexpected block type")
|
||||
|
||||
func (s *service) SetSpaceInfo(spaceId string, details *types.Struct) error {
|
||||
func (s *service) SetSpaceInfo(spaceId string, details *domain.Details) error {
|
||||
ctx := context.TODO()
|
||||
spc, err := s.spaceService.Get(ctx, spaceId)
|
||||
if err != nil {
|
||||
|
@ -34,9 +33,9 @@ func (s *service) SetSpaceInfo(spaceId string, details *types.Struct) error {
|
|||
}
|
||||
workspaceId := spc.DerivedIDs().Workspace
|
||||
|
||||
setDetails := make([]*model.Detail, 0, len(details.GetFields()))
|
||||
for k, v := range details.GetFields() {
|
||||
setDetails = append(setDetails, &model.Detail{
|
||||
setDetails := make([]domain.Detail, 0, details.Len())
|
||||
for k, v := range details.Iterate() {
|
||||
setDetails = append(setDetails, domain.Detail{
|
||||
Key: k,
|
||||
Value: v,
|
||||
})
|
||||
|
@ -49,10 +48,10 @@ func (s *service) SetWorkspaceDashboardId(ctx session.Context, workspaceId strin
|
|||
if ws.Type() != coresb.SmartBlockTypeWorkspace {
|
||||
return ErrUnexpectedBlockType
|
||||
}
|
||||
if err = ws.SetDetails(ctx, []*model.Detail{
|
||||
if err = ws.SetDetails(ctx, []domain.Detail{
|
||||
{
|
||||
Key: bundle.RelationKeySpaceDashboardId.String(),
|
||||
Value: pbtypes.String(id),
|
||||
Key: bundle.RelationKeySpaceDashboardId,
|
||||
Value: domain.StringList([]string{id}),
|
||||
},
|
||||
}, false); err != nil {
|
||||
return err
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/cache"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/basic"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/bookmark"
|
||||
|
@ -26,6 +24,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
var ErrOptionUsedByOtherObjects = fmt.Errorf("option is used by other objects")
|
||||
|
@ -365,7 +364,7 @@ func (s *Service) CreateAndUploadFile(
|
|||
return
|
||||
}
|
||||
|
||||
func (s *Service) UploadFile(ctx context.Context, spaceId string, req FileUploadRequest) (objectId string, details *types.Struct, err error) {
|
||||
func (s *Service) UploadFile(ctx context.Context, spaceId string, req FileUploadRequest) (objectId string, details *domain.Details, err error) {
|
||||
upl := s.fileUploaderService.NewUploader(spaceId, req.ObjectOrigin)
|
||||
if req.DisableEncryption {
|
||||
log.Errorf("DisableEncryption is deprecated and has no effect")
|
||||
|
@ -375,7 +374,7 @@ func (s *Service) UploadFile(ctx context.Context, spaceId string, req FileUpload
|
|||
upl.SetCustomEncryptionKeys(req.CustomEncryptionKeys)
|
||||
}
|
||||
upl.SetStyle(req.Style)
|
||||
upl.SetAdditionalDetails(req.Details)
|
||||
upl.SetAdditionalDetails(domain.NewDetailsFromProto(req.Details))
|
||||
if req.Type != model.BlockContentFile_None {
|
||||
upl.SetType(req.Type)
|
||||
}
|
||||
|
@ -475,7 +474,7 @@ func (s *Service) AddExtraRelations(ctx session.Context, objectId string, relati
|
|||
return nil
|
||||
}
|
||||
return cache.Do(s, objectId, func(b smartblock.SmartBlock) error { // TODO RQ: check if empty
|
||||
return b.AddRelationLinks(ctx, relationIds...)
|
||||
return b.AddRelationLinks(ctx, slice.StringsInto[domain.RelationKey](relationIds)...)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -495,7 +494,7 @@ func (s *Service) SetObjectTypes(ctx session.Context, objectId string, objectTyp
|
|||
|
||||
func (s *Service) RemoveExtraRelations(ctx session.Context, objectTypeId string, relationKeys []string) (err error) {
|
||||
return cache.Do(s, objectTypeId, func(b smartblock.SmartBlock) error {
|
||||
return b.RemoveExtraRelations(ctx, relationKeys)
|
||||
return b.RemoveExtraRelations(ctx, slice.StringsInto[domain.RelationKey](relationKeys))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/anyproto/any-sync/app/logger"
|
||||
"github.com/anyproto/any-sync/commonspace/object/accountdata"
|
||||
"github.com/anyproto/any-sync/util/crypto"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/anytype/config"
|
||||
|
@ -34,7 +33,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/metricsid"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
var log = logger.NewNamedSugared("common.editor.accountobject")
|
||||
|
@ -59,7 +57,7 @@ type AccountObject interface {
|
|||
|
||||
basic.DetailsSettable
|
||||
SetSharedSpacesLimit(limit int) (err error)
|
||||
SetProfileDetails(details *types.Struct) (err error)
|
||||
SetProfileDetails(details *domain.Details) (err error)
|
||||
MigrateIconImage(image string) (err error)
|
||||
IsIconMigrated() (bool, error)
|
||||
SetAnalyticsId(analyticsId string) (err error)
|
||||
|
@ -86,11 +84,11 @@ type accountObject struct {
|
|||
crdtDb anystore.DB
|
||||
}
|
||||
|
||||
func (a *accountObject) SetDetails(ctx session.Context, details []*model.Detail, showEvent bool) (err error) {
|
||||
func (a *accountObject) SetDetails(ctx session.Context, details []domain.Detail, showEvent bool) (err error) {
|
||||
return a.bs.SetDetails(ctx, details, showEvent)
|
||||
}
|
||||
|
||||
func (a *accountObject) SetDetailsAndUpdateLastUsed(ctx session.Context, details []*model.Detail, showEvent bool) (err error) {
|
||||
func (a *accountObject) SetDetailsAndUpdateLastUsed(ctx session.Context, details []domain.Detail, showEvent bool) (err error) {
|
||||
return a.bs.SetDetailsAndUpdateLastUsed(ctx, details, showEvent)
|
||||
}
|
||||
|
||||
|
@ -208,8 +206,8 @@ func (a *accountObject) initState(st *state.State) error {
|
|||
template.InitTemplate(st,
|
||||
template.WithTitle,
|
||||
template.WithForcedObjectTypes([]domain.TypeKey{bundle.TypeKeyProfile}),
|
||||
template.WithForcedDetail(bundle.RelationKeyLayout, pbtypes.Float64(float64(model.ObjectType_profile))),
|
||||
template.WithDetail(bundle.RelationKeyLayoutAlign, pbtypes.Float64(float64(model.Block_AlignCenter))),
|
||||
template.WithForcedDetail(bundle.RelationKeyLayout, domain.Int64(model.ObjectType_profile)),
|
||||
template.WithDetail(bundle.RelationKeyLayoutAlign, domain.Int64(model.Block_AlignCenter)),
|
||||
)
|
||||
blockId := "identity"
|
||||
st.Set(simple.New(&model.Block{
|
||||
|
@ -230,7 +228,7 @@ func (a *accountObject) initState(st *state.State) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("insert block: %w", err)
|
||||
}
|
||||
st.SetDetail(bundle.RelationKeyIsHidden.String(), pbtypes.Bool(true))
|
||||
st.SetDetail(bundle.RelationKeyIsHidden, domain.Bool(true))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -337,19 +335,19 @@ func (a *accountObject) Close() error {
|
|||
|
||||
func (a *accountObject) SetSharedSpacesLimit(limit int) (err error) {
|
||||
st := a.NewState()
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySharedSpacesLimit, pbtypes.Int64(int64(limit)))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySharedSpacesLimit, domain.Int64(limit))
|
||||
return a.Apply(st)
|
||||
}
|
||||
|
||||
func (a *accountObject) GetSharedSpacesLimit() (limit int) {
|
||||
return int(pbtypes.GetInt64(a.CombinedDetails(), bundle.RelationKeySharedSpacesLimit.String()))
|
||||
return int(a.CombinedDetails().GetInt64(bundle.RelationKeySharedSpacesLimit))
|
||||
}
|
||||
|
||||
func (a *accountObject) SetProfileDetails(details *types.Struct) (err error) {
|
||||
func (a *accountObject) SetProfileDetails(details *domain.Details) (err error) {
|
||||
st := a.NewState()
|
||||
// we should set everything in local state, but not everything in the store (this should be filtered in OnPushChange)
|
||||
for key, val := range details.Fields {
|
||||
st.SetDetailAndBundledRelation(domain.RelationKey(key), val)
|
||||
for key, value := range details.Iterate() {
|
||||
st.SetDetailAndBundledRelation(key, value)
|
||||
}
|
||||
return a.Apply(st)
|
||||
}
|
||||
|
@ -357,7 +355,7 @@ func (a *accountObject) SetProfileDetails(details *types.Struct) (err error) {
|
|||
func (a *accountObject) MigrateIconImage(image string) (err error) {
|
||||
if image != "" {
|
||||
st := a.NewState()
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyIconImage, pbtypes.String(image))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyIconImage, domain.String(image))
|
||||
err = a.Apply(st)
|
||||
if err != nil {
|
||||
return fmt.Errorf("set icon image: %w", err)
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/anyproto/any-store/anyenc"
|
||||
"github.com/anyproto/any-sync/commonspace/object/accountdata"
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
|
@ -23,6 +22,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/block/source"
|
||||
"github.com/anyproto/anytype-heart/core/block/source/mock_source"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/util/metricsid"
|
||||
|
@ -133,7 +133,7 @@ func (fx *fixture) assertStoreValue(t *testing.T, test any, extract func(val *an
|
|||
require.Equal(t, test, extract(val))
|
||||
}
|
||||
|
||||
func (fx *fixture) assertStateValue(t *testing.T, val any, extract func(str *types.Struct) any) {
|
||||
func (fx *fixture) assertStateValue(t *testing.T, val any, extract func(str *domain.Details) any) {
|
||||
require.Equal(t, val, extract(fx.SmartBlock.NewState().CombinedDetails()))
|
||||
}
|
||||
|
||||
|
@ -175,11 +175,11 @@ func TestAccountOldInitWithData(t *testing.T) {
|
|||
id, err := fx.GetAnalyticsId()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "analyticsId", id)
|
||||
fx.assertStateValue(t, "Anna", func(str *types.Struct) any {
|
||||
return pbtypes.GetString(str, "name")
|
||||
fx.assertStateValue(t, "Anna", func(str *domain.Details) any {
|
||||
return str.GetString("name")
|
||||
})
|
||||
fx.assertStateValue(t, "Molly", func(str *types.Struct) any {
|
||||
return pbtypes.GetString(str, "description")
|
||||
fx.assertStateValue(t, "Molly", func(str *domain.Details) any {
|
||||
return str.GetString("description")
|
||||
})
|
||||
require.NotNil(t, fx)
|
||||
}
|
||||
|
@ -189,11 +189,11 @@ func TestPushNewChanges(t *testing.T) {
|
|||
fx := newFixture(t, true, nil)
|
||||
_, err := fx.OnPushChange(makeStoreContent(map[string]any{"name": "Anna", "description": "Molly"}))
|
||||
require.NoError(t, err)
|
||||
fx.assertStateValue(t, "Anna", func(str *types.Struct) any {
|
||||
return pbtypes.GetString(str, "name")
|
||||
fx.assertStateValue(t, "Anna", func(str *domain.Details) any {
|
||||
return str.GetString("name")
|
||||
})
|
||||
fx.assertStateValue(t, "Molly", func(str *types.Struct) any {
|
||||
return pbtypes.GetString(str, "description")
|
||||
fx.assertStateValue(t, "Molly", func(str *domain.Details) any {
|
||||
return str.GetString("description")
|
||||
})
|
||||
require.NotNil(t, fx)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"github.com/anyproto/any-store/anyenc"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
)
|
||||
|
||||
type KeyType int
|
||||
|
@ -26,26 +26,26 @@ func newRelationsMapper(keys map[string]KeyType) *relationsMapper {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *relationsMapper) GetRelationKey(key string, val *anyenc.Value) (*types.Value, bool) {
|
||||
func (r *relationsMapper) GetRelationKey(key string, val *anyenc.Value) (domain.Value, bool) {
|
||||
kt, ok := r.keys[key]
|
||||
if !ok {
|
||||
return nil, false
|
||||
return domain.Invalid(), false
|
||||
}
|
||||
switch kt {
|
||||
case KeyTypeString:
|
||||
val := val.GetStringBytes(key)
|
||||
if val == nil {
|
||||
return nil, false
|
||||
return domain.Invalid(), false
|
||||
}
|
||||
return pbtypes.String(string(val)), true
|
||||
return domain.String(string(val)), true
|
||||
case KeyTypeInt64:
|
||||
val := val.GetInt(key)
|
||||
if val == 0 {
|
||||
return nil, false
|
||||
return domain.Invalid(), false
|
||||
}
|
||||
return pbtypes.Int64(int64(val)), true
|
||||
return domain.Int64(int64(val)), true
|
||||
}
|
||||
return nil, false
|
||||
return domain.Invalid(), false
|
||||
}
|
||||
|
||||
func (r *relationsMapper) GetStoreKey(key string, val *types.Value) (res any, ok bool) {
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
|
||||
"github.com/anyproto/any-sync/commonspace/spacestorage"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/collection"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
|
@ -18,7 +17,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/database"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
|
@ -63,7 +61,7 @@ func (p *Archive) CreationStateMigration(ctx *smartblock.InitContext) migration.
|
|||
template.WithNoObjectTypes(),
|
||||
template.WithDetailName("Archive"),
|
||||
template.WithDetailIconEmoji("🗑"),
|
||||
template.WithForcedDetail(bundle.RelationKeyIsHidden, pbtypes.Bool(true)),
|
||||
template.WithForcedDetail(bundle.RelationKeyIsHidden, domain.Bool(true)),
|
||||
)
|
||||
},
|
||||
}
|
||||
|
@ -72,7 +70,7 @@ func (p *Archive) CreationStateMigration(ctx *smartblock.InitContext) migration.
|
|||
func (p *Archive) StateMigrations() migration.Migrations {
|
||||
return migration.MakeMigrations([]migration.Migration{{
|
||||
Version: 2,
|
||||
Proc: template.WithForcedDetail(bundle.RelationKeyIsHidden, pbtypes.Bool(true)),
|
||||
Proc: template.WithForcedDetail(bundle.RelationKeyIsHidden, domain.Bool(true)),
|
||||
}})
|
||||
}
|
||||
|
||||
|
@ -97,9 +95,9 @@ func (p *Archive) updateObjects(_ smartblock.ApplyInfo) (err error) {
|
|||
func (p *Archive) updateInStore(archivedIds []string) error {
|
||||
records, err := p.objectStore.QueryRaw(&database.Filters{FilterObj: database.FiltersAnd{
|
||||
database.FilterEq{
|
||||
Key: bundle.RelationKeyIsArchived.String(),
|
||||
Key: bundle.RelationKeyIsArchived,
|
||||
Cond: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
Value: domain.Bool(true),
|
||||
},
|
||||
}}, 0, 0)
|
||||
if err != nil {
|
||||
|
@ -108,19 +106,17 @@ func (p *Archive) updateInStore(archivedIds []string) error {
|
|||
|
||||
var storeArchivedIds = make([]string, 0, len(records))
|
||||
for _, rec := range records {
|
||||
storeArchivedIds = append(storeArchivedIds, pbtypes.GetString(rec.Details, bundle.RelationKeyId.String()))
|
||||
storeArchivedIds = append(storeArchivedIds, rec.Details.GetString(bundle.RelationKeyId))
|
||||
}
|
||||
|
||||
removedIds, addedIds := slice.DifferenceRemovedAdded(storeArchivedIds, archivedIds)
|
||||
for _, removedId := range removedIds {
|
||||
go func(id string) {
|
||||
if err := p.ModifyLocalDetails(id, func(current *types.Struct) (*types.Struct, error) {
|
||||
if current == nil || current.Fields == nil {
|
||||
current = &types.Struct{
|
||||
Fields: map[string]*types.Value{},
|
||||
}
|
||||
if err := p.ModifyLocalDetails(id, func(current *domain.Details) (*domain.Details, error) {
|
||||
if current == nil {
|
||||
current = domain.NewDetails()
|
||||
}
|
||||
current.Fields[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(false)
|
||||
current.SetBool(bundle.RelationKeyIsArchived, false)
|
||||
return current, nil
|
||||
}); err != nil {
|
||||
logArchiveError(err)
|
||||
|
@ -129,13 +125,11 @@ func (p *Archive) updateInStore(archivedIds []string) error {
|
|||
}
|
||||
for _, addedId := range addedIds {
|
||||
go func(id string) {
|
||||
if err := p.ModifyLocalDetails(id, func(current *types.Struct) (*types.Struct, error) {
|
||||
if current == nil || current.Fields == nil {
|
||||
current = &types.Struct{
|
||||
Fields: map[string]*types.Value{},
|
||||
}
|
||||
if err := p.ModifyLocalDetails(id, func(current *domain.Details) (*domain.Details, error) {
|
||||
if current == nil {
|
||||
current = domain.NewDetails()
|
||||
}
|
||||
current.Fields[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(true)
|
||||
current.SetBool(bundle.RelationKeyIsArchived, true)
|
||||
return current, nil
|
||||
}); err != nil {
|
||||
logArchiveError(err)
|
||||
|
|
|
@ -3,7 +3,6 @@ package basic
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/converter"
|
||||
|
@ -27,7 +26,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
|
@ -65,13 +63,13 @@ type CommonOperations interface {
|
|||
}
|
||||
|
||||
type DetailsSettable interface {
|
||||
SetDetails(ctx session.Context, details []*model.Detail, showEvent bool) (err error)
|
||||
SetDetailsAndUpdateLastUsed(ctx session.Context, details []*model.Detail, showEvent bool) (err error)
|
||||
SetDetails(ctx session.Context, details []domain.Detail, showEvent bool) (err error)
|
||||
SetDetailsAndUpdateLastUsed(ctx session.Context, details []domain.Detail, showEvent bool) (err error)
|
||||
}
|
||||
|
||||
type DetailsUpdatable interface {
|
||||
UpdateDetails(update func(current *types.Struct) (*types.Struct, error)) (err error)
|
||||
UpdateDetailsAndLastUsed(update func(current *types.Struct) (*types.Struct, error)) (err error)
|
||||
UpdateDetails(update func(current *domain.Details) (*domain.Details, error)) (err error)
|
||||
UpdateDetailsAndLastUsed(update func(current *domain.Details) (*domain.Details, error)) (err error)
|
||||
}
|
||||
|
||||
type Restrictionable interface {
|
||||
|
@ -435,7 +433,7 @@ func (bs *basic) AddRelationAndSet(ctx session.Context, req pb.RpcBlockRelationA
|
|||
|
||||
func (bs *basic) FeaturedRelationAdd(ctx session.Context, relations ...string) (err error) {
|
||||
s := bs.NewStateCtx(ctx)
|
||||
fr := pbtypes.GetStringList(s.Details(), bundle.RelationKeyFeaturedRelations.String())
|
||||
fr := s.Details().GetStringList(bundle.RelationKeyFeaturedRelations)
|
||||
frc := make([]string, len(fr))
|
||||
copy(frc, fr)
|
||||
for _, r := range relations {
|
||||
|
@ -447,7 +445,7 @@ func (bs *basic) FeaturedRelationAdd(ctx session.Context, relations ...string) (
|
|||
}
|
||||
frc = append(frc, r)
|
||||
if !bs.HasRelation(s, r) {
|
||||
err = bs.addRelationLink(s, r)
|
||||
err = bs.addRelationLink(s, domain.RelationKey(r))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add relation link on adding featured relation '%s': %w", r, err)
|
||||
}
|
||||
|
@ -455,14 +453,14 @@ func (bs *basic) FeaturedRelationAdd(ctx session.Context, relations ...string) (
|
|||
}
|
||||
}
|
||||
if len(frc) != len(fr) {
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations.String(), pbtypes.StringList(frc))
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations, domain.StringList(frc))
|
||||
}
|
||||
return bs.Apply(s, smartblock.NoRestrictions)
|
||||
}
|
||||
|
||||
func (bs *basic) FeaturedRelationRemove(ctx session.Context, relations ...string) (err error) {
|
||||
s := bs.NewStateCtx(ctx)
|
||||
fr := pbtypes.GetStringList(s.Details(), bundle.RelationKeyFeaturedRelations.String())
|
||||
fr := s.Details().GetStringList(bundle.RelationKeyFeaturedRelations)
|
||||
frc := make([]string, len(fr))
|
||||
copy(frc, fr)
|
||||
for _, r := range relations {
|
||||
|
@ -476,7 +474,7 @@ func (bs *basic) FeaturedRelationRemove(ctx session.Context, relations ...string
|
|||
}
|
||||
}
|
||||
if len(frc) != len(fr) {
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations.String(), pbtypes.StringList(frc))
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations, domain.StringList(frc))
|
||||
}
|
||||
return bs.Apply(s, smartblock.NoRestrictions)
|
||||
}
|
||||
|
@ -504,8 +502,9 @@ func (bs *basic) ReplaceLink(oldId, newId string) error {
|
|||
details := s.Details()
|
||||
for _, rel := range rels {
|
||||
if rel.Format == model.RelationFormat_object {
|
||||
if pbtypes.GetString(details, rel.Key) == oldId {
|
||||
s.SetDetail(rel.Key, pbtypes.String(newId))
|
||||
key := domain.RelationKey(rel.Key)
|
||||
if details.GetString(key) == oldId {
|
||||
s.SetDetail(key, domain.String(newId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,12 +164,12 @@ func TestBasic_Duplicate(t *testing.T) {
|
|||
AddBlock(simple.New(&model.Block{Id: "f1", Content: &model.BlockContentOfFile{File: &model.BlockContentFile{TargetObjectId: "file1_space1"}}})).
|
||||
AddBlock(simple.New(&model.Block{Id: "f2", Content: &model.BlockContentOfFile{File: &model.BlockContentFile{TargetObjectId: "file2_space1"}}}))
|
||||
ss := source.NewState()
|
||||
ss.SetDetail(bundle.RelationKeySpaceId.String(), pbtypes.String(tc.spaceIds[0]))
|
||||
ss.SetDetail(bundle.RelationKeySpaceId, domain.String(tc.spaceIds[0]))
|
||||
|
||||
target := smarttest.New("target").
|
||||
AddBlock(simple.New(&model.Block{Id: "target"}))
|
||||
ts := target.NewState()
|
||||
ts.SetDetail(bundle.RelationKeySpaceId.String(), pbtypes.String(tc.spaceIds[1]))
|
||||
ts.SetDetail(bundle.RelationKeySpaceId, domain.String(tc.spaceIds[1]))
|
||||
|
||||
// when
|
||||
newIds, err := NewBasic(source, nil, nil, tc.fos(), nil).Duplicate(ss, ts, "target", model.Block_Inner, []string{"1", "f1"})
|
||||
|
@ -666,14 +666,14 @@ func TestBasic_FeaturedRelationAdd(t *testing.T) {
|
|||
require.NoError(t, b.FeaturedRelationAdd(nil, newRel...))
|
||||
|
||||
res := sb.NewState()
|
||||
assert.Equal(t, newRel, pbtypes.GetStringList(res.Details(), bundle.RelationKeyFeaturedRelations.String()))
|
||||
assert.Equal(t, newRel, res.Details().GetStringList(bundle.RelationKeyFeaturedRelations))
|
||||
assert.NotNil(t, res.Pick(template.DescriptionBlockId))
|
||||
}
|
||||
|
||||
func TestBasic_FeaturedRelationRemove(t *testing.T) {
|
||||
sb := smarttest.New("test")
|
||||
s := sb.NewState()
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations.String(), pbtypes.StringList([]string{bundle.RelationKeyDescription.String(), bundle.RelationKeyName.String()}))
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations, domain.StringList([]string{bundle.RelationKeyDescription.String(), bundle.RelationKeyName.String()}))
|
||||
template.WithDescription(s)
|
||||
require.NoError(t, sb.Apply(s))
|
||||
|
||||
|
@ -681,7 +681,7 @@ func TestBasic_FeaturedRelationRemove(t *testing.T) {
|
|||
require.NoError(t, b.FeaturedRelationRemove(nil, bundle.RelationKeyDescription.String()))
|
||||
|
||||
res := sb.NewState()
|
||||
assert.Equal(t, []string{bundle.RelationKeyName.String()}, pbtypes.GetStringList(res.Details(), bundle.RelationKeyFeaturedRelations.String()))
|
||||
assert.Equal(t, []string{bundle.RelationKeyName.String()}, res.Details().GetStringList(bundle.RelationKeyFeaturedRelations))
|
||||
assert.Nil(t, res.PickParentOf(template.DescriptionBlockId))
|
||||
}
|
||||
|
||||
|
@ -690,7 +690,7 @@ func TestBasic_ReplaceLink(t *testing.T) {
|
|||
|
||||
sb := smarttest.New("test")
|
||||
s := sb.NewState()
|
||||
s.SetDetail("link", pbtypes.String(oldId))
|
||||
s.SetDetail("link", domain.String(oldId))
|
||||
s.AddRelationLinks(&model.RelationLink{Key: "link", Format: model.RelationFormat_object})
|
||||
template.WithDescription(s)
|
||||
newBlocks := []simple.Block{
|
||||
|
@ -718,7 +718,7 @@ func TestBasic_ReplaceLink(t *testing.T) {
|
|||
require.NoError(t, b.ReplaceLink(oldId, newId))
|
||||
|
||||
res := sb.NewState()
|
||||
assert.Equal(t, newId, pbtypes.GetString(res.Details(), "link"))
|
||||
assert.Equal(t, newId, res.Details().GetString("link"))
|
||||
assert.Equal(t, newId, res.Pick(newBlocks[0].Model().Id).Model().GetLink().TargetBlockId)
|
||||
assert.Equal(t, newId, res.Pick(newBlocks[1].Model().Id).Model().GetText().GetMarks().Marks[0].Param)
|
||||
}
|
||||
|
|
|
@ -6,9 +6,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/block/restriction"
|
||||
|
@ -21,23 +18,17 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/logging"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/internalflag"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/uri"
|
||||
)
|
||||
|
||||
var log = logging.Logger("anytype-mw-editor-basic")
|
||||
|
||||
type detailUpdate struct {
|
||||
key string
|
||||
value *types.Value
|
||||
}
|
||||
|
||||
func (bs *basic) SetDetails(ctx session.Context, details []*model.Detail, showEvent bool) (err error) {
|
||||
func (bs *basic) SetDetails(ctx session.Context, details []domain.Detail, showEvent bool) (err error) {
|
||||
_, err = bs.setDetails(ctx, details, showEvent)
|
||||
return err
|
||||
}
|
||||
|
||||
func (bs *basic) SetDetailsAndUpdateLastUsed(ctx session.Context, details []*model.Detail, showEvent bool) (err error) {
|
||||
func (bs *basic) SetDetailsAndUpdateLastUsed(ctx session.Context, details []domain.Detail, showEvent bool) (err error) {
|
||||
var keys []domain.RelationKey
|
||||
keys, err = bs.setDetails(ctx, details, showEvent)
|
||||
if err != nil {
|
||||
|
@ -50,7 +41,7 @@ func (bs *basic) SetDetailsAndUpdateLastUsed(ctx session.Context, details []*mod
|
|||
return nil
|
||||
}
|
||||
|
||||
func (bs *basic) setDetails(ctx session.Context, details []*model.Detail, showEvent bool) (updatedKeys []domain.RelationKey, err error) {
|
||||
func (bs *basic) setDetails(ctx session.Context, details []domain.Detail, showEvent bool) (updatedKeys []domain.RelationKey, err error) {
|
||||
s := bs.NewStateCtx(ctx)
|
||||
|
||||
// Collect updates handling special cases. These cases could update details themselves, so we
|
||||
|
@ -71,37 +62,36 @@ func (bs *basic) setDetails(ctx session.Context, details []*model.Detail, showEv
|
|||
return updatedKeys, nil
|
||||
}
|
||||
|
||||
func (bs *basic) UpdateDetails(update func(current *types.Struct) (*types.Struct, error)) (err error) {
|
||||
func (bs *basic) UpdateDetails(update func(current *domain.Details) (*domain.Details, error)) (err error) {
|
||||
_, _, err = bs.updateDetails(update)
|
||||
return err
|
||||
}
|
||||
|
||||
func (bs *basic) UpdateDetailsAndLastUsed(update func(current *types.Struct) (*types.Struct, error)) (err error) {
|
||||
var oldDetails, newDetails *types.Struct
|
||||
oldDetails, newDetails, err = bs.updateDetails(update)
|
||||
func (bs *basic) UpdateDetailsAndLastUsed(update func(current *domain.Details) (*domain.Details, error)) error {
|
||||
oldDetails, newDetails, err := bs.updateDetails(update)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
diff := pbtypes.StructDiff(oldDetails, newDetails)
|
||||
if diff == nil || diff.Fields == nil {
|
||||
diff := domain.StructDiff(oldDetails, newDetails)
|
||||
if diff.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
ts := time.Now().Unix()
|
||||
for key := range diff.Fields {
|
||||
bs.lastUsedUpdater.UpdateLastUsedDate(bs.SpaceID(), domain.RelationKey(key), ts)
|
||||
for _, key := range diff.Keys() {
|
||||
bs.lastUsedUpdater.UpdateLastUsedDate(bs.SpaceID(), key, ts)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bs *basic) updateDetails(update func(current *types.Struct) (*types.Struct, error)) (oldDetails, newDetails *types.Struct, err error) {
|
||||
func (bs *basic) updateDetails(update func(current *domain.Details) (*domain.Details, error)) (oldDetails *domain.Details, newDetails *domain.Details, err error) {
|
||||
if update == nil {
|
||||
return nil, nil, fmt.Errorf("update function is nil")
|
||||
}
|
||||
s := bs.NewState()
|
||||
|
||||
oldDetails = s.CombinedDetails()
|
||||
oldDetailsCopy := pbtypes.CopyStruct(oldDetails, true)
|
||||
oldDetailsCopy := oldDetails.Copy()
|
||||
|
||||
newDetails, err = update(oldDetailsCopy)
|
||||
if err != nil {
|
||||
|
@ -109,21 +99,21 @@ func (bs *basic) updateDetails(update func(current *types.Struct) (*types.Struct
|
|||
}
|
||||
s.SetDetails(newDetails)
|
||||
|
||||
if err = bs.addRelationLinks(s, maps.Keys(newDetails.Fields)...); err != nil {
|
||||
if err = bs.addRelationLinks(s, newDetails.Keys()...); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return oldDetails, newDetails, bs.Apply(s)
|
||||
}
|
||||
|
||||
func (bs *basic) collectDetailUpdates(details []*model.Detail, s *state.State) ([]*detailUpdate, []domain.RelationKey) {
|
||||
updates := make([]*detailUpdate, 0, len(details))
|
||||
func (bs *basic) collectDetailUpdates(details []domain.Detail, s *state.State) ([]domain.Detail, []domain.RelationKey) {
|
||||
updates := make([]domain.Detail, 0, len(details))
|
||||
keys := make([]domain.RelationKey, 0, len(details))
|
||||
for _, detail := range details {
|
||||
update, err := bs.createDetailUpdate(s, detail)
|
||||
if err == nil {
|
||||
updates = append(updates, update)
|
||||
keys = append(keys, domain.RelationKey(update.key))
|
||||
keys = append(keys, update.Key)
|
||||
} else {
|
||||
log.Errorf("can't set detail %s: %s", detail.Key, err)
|
||||
}
|
||||
|
@ -131,129 +121,120 @@ func (bs *basic) collectDetailUpdates(details []*model.Detail, s *state.State) (
|
|||
return updates, keys
|
||||
}
|
||||
|
||||
func applyDetailUpdates(oldDetails *types.Struct, updates []*detailUpdate) *types.Struct {
|
||||
newDetails := pbtypes.CopyStruct(oldDetails, false)
|
||||
if newDetails == nil || newDetails.Fields == nil {
|
||||
newDetails = &types.Struct{
|
||||
Fields: make(map[string]*types.Value),
|
||||
}
|
||||
func applyDetailUpdates(oldDetails *domain.Details, updates []domain.Detail) *domain.Details {
|
||||
newDetails := oldDetails.Copy()
|
||||
if newDetails == nil {
|
||||
newDetails = domain.NewDetails()
|
||||
}
|
||||
for _, update := range updates {
|
||||
if update.value == nil {
|
||||
delete(newDetails.Fields, update.key)
|
||||
if update.Value.IsNull() {
|
||||
newDetails.Delete(update.Key)
|
||||
} else {
|
||||
newDetails.Fields[update.key] = update.value
|
||||
newDetails.Set(update.Key, update.Value)
|
||||
}
|
||||
}
|
||||
return newDetails
|
||||
}
|
||||
|
||||
func (bs *basic) createDetailUpdate(st *state.State, detail *model.Detail) (*detailUpdate, error) {
|
||||
if detail.Value != nil {
|
||||
if err := pbtypes.ValidateValue(detail.Value); err != nil {
|
||||
return nil, fmt.Errorf("detail %s validation error: %w", detail.Key, err)
|
||||
}
|
||||
// TODO make no sense?
|
||||
func (bs *basic) createDetailUpdate(st *state.State, detail domain.Detail) (domain.Detail, error) {
|
||||
if detail.Value.Ok() {
|
||||
if err := bs.setDetailSpecialCases(st, detail); err != nil {
|
||||
return nil, fmt.Errorf("special case: %w", err)
|
||||
return domain.Detail{}, fmt.Errorf("special case: %w", err)
|
||||
}
|
||||
if err := bs.addRelationLink(st, detail.Key); err != nil {
|
||||
return nil, err
|
||||
return domain.Detail{}, err
|
||||
}
|
||||
if err := bs.validateDetailFormat(bs.SpaceID(), detail.Key, detail.Value); err != nil {
|
||||
return nil, fmt.Errorf("failed to validate relation: %w", err)
|
||||
return domain.Detail{}, fmt.Errorf("failed to validate relation: %w", err)
|
||||
}
|
||||
}
|
||||
return &detailUpdate{
|
||||
key: detail.Key,
|
||||
value: detail.Value,
|
||||
return domain.Detail{
|
||||
Key: detail.Key,
|
||||
Value: detail.Value,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (bs *basic) validateDetailFormat(spaceID string, key string, v *types.Value) error {
|
||||
r, err := bs.objectStore.FetchRelationByKey(key)
|
||||
func (bs *basic) validateDetailFormat(spaceID string, key domain.RelationKey, v domain.Value) error {
|
||||
if !v.Ok() {
|
||||
return fmt.Errorf("invalid value")
|
||||
}
|
||||
r, err := bs.objectStore.FetchRelationByKey(key.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, isNull := v.Kind.(*types.Value_NullValue); isNull {
|
||||
if v.IsNull() {
|
||||
// allow null value for any field
|
||||
return nil
|
||||
}
|
||||
|
||||
switch r.Format {
|
||||
case model.RelationFormat_longtext, model.RelationFormat_shorttext:
|
||||
if _, ok := v.Kind.(*types.Value_StringValue); !ok {
|
||||
return fmt.Errorf("incorrect type: %T instead of string", v.Kind)
|
||||
if !v.IsString() {
|
||||
return fmt.Errorf("incorrect type: %v instead of string", v)
|
||||
}
|
||||
return nil
|
||||
case model.RelationFormat_number:
|
||||
if _, ok := v.Kind.(*types.Value_NumberValue); !ok {
|
||||
return fmt.Errorf("incorrect type: %T instead of number", v.Kind)
|
||||
if !v.IsFloat64() {
|
||||
return fmt.Errorf("incorrect type: %v instead of number", v)
|
||||
}
|
||||
return nil
|
||||
case model.RelationFormat_status:
|
||||
if _, ok := v.Kind.(*types.Value_StringValue); ok {
|
||||
|
||||
} else if _, ok := v.Kind.(*types.Value_ListValue); !ok {
|
||||
return fmt.Errorf("incorrect type: %T instead of list", v.Kind)
|
||||
vals, ok := v.TryStringList()
|
||||
if !ok {
|
||||
return fmt.Errorf("incorrect type: %v instead of string list", v)
|
||||
}
|
||||
|
||||
vals := pbtypes.GetStringListValue(v)
|
||||
if len(vals) > 1 {
|
||||
return fmt.Errorf("status should not contain more than one value")
|
||||
}
|
||||
return bs.validateOptions(r, vals)
|
||||
|
||||
case model.RelationFormat_tag:
|
||||
if _, ok := v.Kind.(*types.Value_ListValue); !ok {
|
||||
return fmt.Errorf("incorrect type: %T instead of list", v.Kind)
|
||||
vals, ok := v.TryStringList()
|
||||
if !ok {
|
||||
return fmt.Errorf("incorrect type: %v instead of string list", v)
|
||||
}
|
||||
|
||||
vals := pbtypes.GetStringListValue(v)
|
||||
if r.MaxCount > 0 && len(vals) > int(r.MaxCount) {
|
||||
return fmt.Errorf("maxCount exceeded")
|
||||
}
|
||||
|
||||
return bs.validateOptions(r, vals)
|
||||
case model.RelationFormat_date:
|
||||
if _, ok := v.Kind.(*types.Value_NumberValue); !ok {
|
||||
return fmt.Errorf("incorrect type: %T instead of number", v.Kind)
|
||||
if !v.IsFloat64() {
|
||||
return fmt.Errorf("incorrect type: %v instead of number", v)
|
||||
}
|
||||
|
||||
return nil
|
||||
case model.RelationFormat_file, model.RelationFormat_object:
|
||||
switch s := v.Kind.(type) {
|
||||
case *types.Value_StringValue:
|
||||
return nil
|
||||
case *types.Value_ListValue:
|
||||
if r.MaxCount > 0 && len(s.ListValue.Values) > int(r.MaxCount) {
|
||||
return fmt.Errorf("relation %s(%s) has maxCount exceeded", r.Key, r.Format.String())
|
||||
}
|
||||
|
||||
for i, lv := range s.ListValue.Values {
|
||||
if optId, ok := lv.Kind.(*types.Value_StringValue); !ok {
|
||||
return fmt.Errorf("incorrect list item value at index %d: %T instead of string", i, lv.Kind)
|
||||
} else if optId.StringValue == "" {
|
||||
return fmt.Errorf("empty option at index %d", i)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("incorrect type: %T instead of list/string", v.Kind)
|
||||
vals, ok := v.TryStringList()
|
||||
if !ok {
|
||||
return fmt.Errorf("incorrect type: %v instead of string list", v)
|
||||
}
|
||||
if r.MaxCount > 0 && len(vals) > int(r.MaxCount) {
|
||||
return fmt.Errorf("relation %s(%s) has maxCount exceeded", r.Key, r.Format.String())
|
||||
}
|
||||
|
||||
for i, lv := range vals {
|
||||
if lv == "" {
|
||||
return fmt.Errorf("empty option at index %d", i)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case model.RelationFormat_checkbox:
|
||||
if _, ok := v.Kind.(*types.Value_BoolValue); !ok {
|
||||
return fmt.Errorf("incorrect type: %T instead of bool", v.Kind)
|
||||
if !v.IsBool() {
|
||||
return fmt.Errorf("incorrect type: %v instead of bool", v)
|
||||
}
|
||||
|
||||
return nil
|
||||
case model.RelationFormat_url:
|
||||
if _, ok := v.Kind.(*types.Value_StringValue); !ok {
|
||||
return fmt.Errorf("incorrect type: %T instead of string", v.Kind)
|
||||
val, ok := v.TryString()
|
||||
if !ok {
|
||||
return fmt.Errorf("incorrect type: %v instead of string", v)
|
||||
}
|
||||
|
||||
s := strings.TrimSpace(v.GetStringValue())
|
||||
s := strings.TrimSpace(val)
|
||||
if s != "" {
|
||||
err := uri.ValidateURI(strings.TrimSpace(v.GetStringValue()))
|
||||
err := uri.ValidateURI(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse URL: %w", err)
|
||||
}
|
||||
|
@ -264,8 +245,9 @@ func (bs *basic) validateDetailFormat(spaceID string, key string, v *types.Value
|
|||
// }
|
||||
return nil
|
||||
case model.RelationFormat_email:
|
||||
if _, ok := v.Kind.(*types.Value_StringValue); !ok {
|
||||
return fmt.Errorf("incorrect type: %T instead of string", v.Kind)
|
||||
_, ok := v.TryString()
|
||||
if !ok {
|
||||
return fmt.Errorf("incorrect type: %v instead of string", v)
|
||||
}
|
||||
// todo: revise regexp and reimplement
|
||||
/*valid := uri.ValidateEmail(v.GetStringValue())
|
||||
|
@ -274,8 +256,9 @@ func (bs *basic) validateDetailFormat(spaceID string, key string, v *types.Value
|
|||
}*/
|
||||
return nil
|
||||
case model.RelationFormat_phone:
|
||||
if _, ok := v.Kind.(*types.Value_StringValue); !ok {
|
||||
return fmt.Errorf("incorrect type: %T instead of string", v.Kind)
|
||||
_, ok := v.TryString()
|
||||
if !ok {
|
||||
return fmt.Errorf("incorrect type: %v instead of string", v)
|
||||
}
|
||||
|
||||
// todo: revise regexp and reimplement
|
||||
|
@ -285,8 +268,9 @@ func (bs *basic) validateDetailFormat(spaceID string, key string, v *types.Value
|
|||
}*/
|
||||
return nil
|
||||
case model.RelationFormat_emoji:
|
||||
if _, ok := v.Kind.(*types.Value_StringValue); !ok {
|
||||
return fmt.Errorf("incorrect type: %T instead of string", v.Kind)
|
||||
_, ok := v.TryString()
|
||||
if !ok {
|
||||
return fmt.Errorf("incorrect type: %v instead of string", v)
|
||||
}
|
||||
|
||||
// check if the symbol is emoji
|
||||
|
@ -301,19 +285,19 @@ func (bs *basic) validateOptions(rel *relationutils.Relation, v []string) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func (bs *basic) setDetailSpecialCases(st *state.State, detail *model.Detail) error {
|
||||
if detail.Key == bundle.RelationKeyType.String() {
|
||||
func (bs *basic) setDetailSpecialCases(st *state.State, detail domain.Detail) error {
|
||||
if detail.Key == bundle.RelationKeyType {
|
||||
return fmt.Errorf("can't change object type directly: %w", domain.ErrValidationFailed)
|
||||
}
|
||||
if detail.Key == bundle.RelationKeyLayout.String() {
|
||||
if detail.Key == bundle.RelationKeyLayout {
|
||||
// special case when client sets the layout detail directly instead of using SetLayoutInState command
|
||||
return bs.SetLayoutInState(st, model.ObjectTypeLayout(detail.Value.GetNumberValue()), false)
|
||||
return bs.SetLayoutInState(st, model.ObjectTypeLayout(detail.Value.Int64()), false)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bs *basic) addRelationLink(st *state.State, relationKey string) error {
|
||||
relLink, err := bs.objectStore.GetRelationLink(relationKey)
|
||||
func (bs *basic) addRelationLink(st *state.State, relationKey domain.RelationKey) error {
|
||||
relLink, err := bs.objectStore.GetRelationLink(relationKey.String())
|
||||
if err != nil || relLink == nil {
|
||||
return fmt.Errorf("failed to get relation: %w", err)
|
||||
}
|
||||
|
@ -322,7 +306,7 @@ func (bs *basic) addRelationLink(st *state.State, relationKey string) error {
|
|||
}
|
||||
|
||||
// addRelationLinks is deprecated and will be removed in release 7
|
||||
func (bs *basic) addRelationLinks(st *state.State, relationKeys ...string) error {
|
||||
func (bs *basic) addRelationLinks(st *state.State, relationKeys ...domain.RelationKey) error {
|
||||
if len(relationKeys) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
@ -394,7 +378,7 @@ func (bs *basic) SetObjectTypesInState(s *state.State, objectTypeKeys []domain.T
|
|||
s.SetObjectTypeKeys(objectTypeKeys)
|
||||
removeInternalFlags(s)
|
||||
|
||||
if pbtypes.GetInt64(bs.CombinedDetails(), bundle.RelationKeyOrigin.String()) == int64(model.ObjectOrigin_none) {
|
||||
if bs.CombinedDetails().GetInt64(bundle.RelationKeyOrigin) == int64(model.ObjectOrigin_none) {
|
||||
bs.lastUsedUpdater.UpdateLastUsedDate(bs.SpaceID(), objectTypeKeys[0], time.Now().Unix())
|
||||
}
|
||||
|
||||
|
@ -414,7 +398,7 @@ func (bs *basic) getLayoutForType(objectTypeKey domain.TypeKey) (model.ObjectTyp
|
|||
if err != nil {
|
||||
return 0, fmt.Errorf("get object by unique key: %w", err)
|
||||
}
|
||||
rawLayout := pbtypes.GetInt64(typeDetails.GetDetails(), bundle.RelationKeyRecommendedLayout.String())
|
||||
rawLayout := typeDetails.GetInt64(bundle.RelationKeyRecommendedLayout)
|
||||
return model.ObjectTypeLayout(rawLayout), nil
|
||||
}
|
||||
|
||||
|
@ -426,7 +410,7 @@ func (bs *basic) SetLayoutInState(s *state.State, toLayout model.ObjectTypeLayou
|
|||
}
|
||||
|
||||
fromLayout, _ := s.Layout()
|
||||
s.SetDetail(bundle.RelationKeyLayout.String(), pbtypes.Int64(int64(toLayout)))
|
||||
s.SetDetail(bundle.RelationKeyLayout, domain.Int64(toLayout))
|
||||
if err = bs.layoutConverter.Convert(s, fromLayout, toLayout); err != nil {
|
||||
return fmt.Errorf("convert layout: %w", err)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package basic
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
|
@ -16,7 +15,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
type basicFixture struct {
|
||||
|
@ -54,92 +52,94 @@ func TestBasic_UpdateDetails(t *testing.T) {
|
|||
// given
|
||||
f := newBasicFixture(t)
|
||||
f.store.AddObjects(t, []objectstore.TestObject{{
|
||||
bundle.RelationKeyId: pbtypes.String("rel-aperture"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyRelationKey: pbtypes.String("aperture"),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String("rel-aperture"),
|
||||
bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_longtext)),
|
||||
bundle.RelationKeyId: domain.String("rel-aperture"),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyRelationKey: domain.String("aperture"),
|
||||
bundle.RelationKeyUniqueKey: domain.String("rel-aperture"),
|
||||
bundle.RelationKeyRelationFormat: domain.Int64(int64(model.RelationFormat_longtext)),
|
||||
}, {
|
||||
bundle.RelationKeyId: pbtypes.String("rel-maxCount"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyRelationKey: pbtypes.String("relationMaxCount"),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String("rel-relationMaxCount"),
|
||||
bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_number)),
|
||||
bundle.RelationKeyId: domain.String("rel-maxCount"),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyRelationKey: domain.String("relationMaxCount"),
|
||||
bundle.RelationKeyUniqueKey: domain.String("rel-relationMaxCount"),
|
||||
bundle.RelationKeyRelationFormat: domain.Int64(int64(model.RelationFormat_number)),
|
||||
}})
|
||||
|
||||
// when
|
||||
err := f.basic.UpdateDetails(func(current *types.Struct) (*types.Struct, error) {
|
||||
current.Fields[bundle.RelationKeyAperture.String()] = pbtypes.String("aperture")
|
||||
current.Fields[bundle.RelationKeyRelationMaxCount.String()] = pbtypes.Int64(5)
|
||||
err := f.basic.UpdateDetails(func(current *domain.Details) (*domain.Details, error) {
|
||||
current.Set(bundle.RelationKeyAperture, domain.String("aperture"))
|
||||
current.Set(bundle.RelationKeyRelationMaxCount, domain.Int64(5))
|
||||
return current, nil
|
||||
})
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
|
||||
value, found := f.sb.Details().Fields[bundle.RelationKeyAperture.String()]
|
||||
value, found := f.sb.Details().TryString(bundle.RelationKeyAperture)
|
||||
assert.True(t, found)
|
||||
assert.Equal(t, pbtypes.String("aperture"), value)
|
||||
assert.Equal(t, "aperture", value)
|
||||
assert.True(t, f.sb.HasRelation(f.sb.NewState(), bundle.RelationKeyAperture.String()))
|
||||
|
||||
value, found = f.sb.Details().Fields[bundle.RelationKeyRelationMaxCount.String()]
|
||||
assert.True(t, found)
|
||||
assert.Equal(t, pbtypes.Int64(5), value)
|
||||
assert.True(t, f.sb.HasRelation(f.sb.NewState(), bundle.RelationKeyRelationMaxCount.String()))
|
||||
{
|
||||
value, found := f.sb.Details().TryInt64(bundle.RelationKeyRelationMaxCount)
|
||||
assert.True(t, found)
|
||||
assert.Equal(t, int64(5), value)
|
||||
assert.True(t, f.sb.HasRelation(f.sb.NewState(), bundle.RelationKeyRelationMaxCount.String()))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("modify details", func(t *testing.T) {
|
||||
// given
|
||||
f := newBasicFixture(t)
|
||||
err := f.sb.SetDetails(nil, []*model.Detail{{
|
||||
Key: bundle.RelationKeySpaceDashboardId.String(),
|
||||
Value: pbtypes.String("123"),
|
||||
err := f.sb.SetDetails(nil, []domain.Detail{{
|
||||
Key: bundle.RelationKeySpaceDashboardId,
|
||||
Value: domain.String("123"),
|
||||
}}, false)
|
||||
assert.NoError(t, err)
|
||||
f.store.AddObjects(t, []objectstore.TestObject{{
|
||||
bundle.RelationKeyId: pbtypes.String("rel-spaceDashboardId"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyRelationKey: pbtypes.String("spaceDashboardId"),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String("rel-spaceDashboardId"),
|
||||
bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_object)),
|
||||
bundle.RelationKeyId: domain.String("rel-spaceDashboardId"),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyRelationKey: domain.String("spaceDashboardId"),
|
||||
bundle.RelationKeyUniqueKey: domain.String("rel-spaceDashboardId"),
|
||||
bundle.RelationKeyRelationFormat: domain.Int64(int64(model.RelationFormat_object)),
|
||||
}})
|
||||
|
||||
// when
|
||||
err = f.basic.UpdateDetails(func(current *types.Struct) (*types.Struct, error) {
|
||||
current.Fields[bundle.RelationKeySpaceDashboardId.String()] = pbtypes.String("new123")
|
||||
err = f.basic.UpdateDetails(func(current *domain.Details) (*domain.Details, error) {
|
||||
current.Set(bundle.RelationKeySpaceDashboardId, domain.String("new123"))
|
||||
return current, nil
|
||||
})
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
|
||||
value, found := f.sb.Details().Fields[bundle.RelationKeySpaceDashboardId.String()]
|
||||
value, found := f.sb.Details().TryString(bundle.RelationKeySpaceDashboardId)
|
||||
assert.True(t, found)
|
||||
assert.Equal(t, pbtypes.String("new123"), value)
|
||||
assert.Equal(t, "new123", value)
|
||||
assert.True(t, f.sb.HasRelation(f.sb.NewState(), bundle.RelationKeySpaceDashboardId.String()))
|
||||
})
|
||||
|
||||
t.Run("delete details", func(t *testing.T) {
|
||||
// given
|
||||
f := newBasicFixture(t)
|
||||
err := f.sb.SetDetails(nil, []*model.Detail{{
|
||||
Key: bundle.RelationKeyTargetObjectType.String(),
|
||||
Value: pbtypes.String("ot-note"),
|
||||
err := f.sb.SetDetails(nil, []domain.Detail{{
|
||||
Key: bundle.RelationKeyTargetObjectType,
|
||||
Value: domain.String("ot-note"),
|
||||
}}, false)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// when
|
||||
err = f.basic.UpdateDetails(func(current *types.Struct) (*types.Struct, error) {
|
||||
delete(current.Fields, bundle.RelationKeyTargetObjectType.String())
|
||||
err = f.basic.UpdateDetails(func(current *domain.Details) (*domain.Details, error) {
|
||||
current.Delete(bundle.RelationKeyTargetObjectType)
|
||||
return current, nil
|
||||
})
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
|
||||
value, found := f.sb.Details().Fields[bundle.RelationKeyTargetObjectType.String()]
|
||||
value, found := f.sb.Details().TryString(bundle.RelationKeyTargetObjectType)
|
||||
assert.False(t, found)
|
||||
assert.Nil(t, value)
|
||||
assert.Empty(t, value)
|
||||
assert.False(t, f.sb.HasRelation(f.sb.NewState(), bundle.RelationKeyTargetObjectType.String()))
|
||||
})
|
||||
}
|
||||
|
@ -151,10 +151,10 @@ func TestBasic_SetObjectTypesInState(t *testing.T) {
|
|||
|
||||
f.lastUsed.EXPECT().UpdateLastUsedDate(mock.Anything, bundle.TypeKeyTask, mock.Anything).Return().Once()
|
||||
f.store.AddObjects(t, []objectstore.TestObject{{
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyId: pbtypes.String("ot-task"),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String("ot-task"),
|
||||
bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_todo)),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyId: domain.String("ot-task"),
|
||||
bundle.RelationKeyUniqueKey: domain.String("ot-task"),
|
||||
bundle.RelationKeyLayout: domain.Int64(int64(model.ObjectType_todo)),
|
||||
}})
|
||||
|
||||
s := f.sb.NewState()
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
|
@ -19,12 +18,12 @@ import (
|
|||
)
|
||||
|
||||
type ObjectCreator interface {
|
||||
CreateSmartBlockFromState(ctx context.Context, spaceID string, objectTypeKeys []domain.TypeKey, createState *state.State) (id string, newDetails *types.Struct, err error)
|
||||
CreateSmartBlockFromState(ctx context.Context, spaceID string, objectTypeKeys []domain.TypeKey, createState *state.State) (id string, newDetails *domain.Details, err error)
|
||||
}
|
||||
|
||||
type TemplateStateCreator interface {
|
||||
CreateTemplateStateWithDetails(templateId string, details *types.Struct) (*state.State, error)
|
||||
CreateTemplateStateFromSmartBlock(sb smartblock.SmartBlock, details *types.Struct) *state.State
|
||||
CreateTemplateStateWithDetails(templateId string, details *domain.Details) (*state.State, error)
|
||||
CreateTemplateStateFromSmartBlock(sb smartblock.SmartBlock, details *domain.Details) *state.State
|
||||
}
|
||||
|
||||
// ExtractBlocksToObjects extracts child blocks from the object to separate objects and
|
||||
|
@ -94,12 +93,12 @@ func (bs *basic) prepareTargetObjectDetails(
|
|||
spaceID string,
|
||||
typeUniqueKey domain.UniqueKey,
|
||||
rootBlock simple.Block,
|
||||
) (*types.Struct, error) {
|
||||
) (*domain.Details, error) {
|
||||
objType, err := bs.objectStore.GetObjectByUniqueKey(typeUniqueKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rawLayout := pbtypes.GetInt64(objType.GetDetails(), bundle.RelationKeyRecommendedLayout.String())
|
||||
rawLayout := objType.GetInt64(bundle.RelationKeyRecommendedLayout)
|
||||
details := createTargetObjectDetails(rootBlock.Model().GetText().GetText(), model.ObjectTypeLayout(rawLayout))
|
||||
return details, nil
|
||||
}
|
||||
|
@ -177,17 +176,13 @@ func removeBlocks(state *state.State, descendants []simple.Block) {
|
|||
}
|
||||
}
|
||||
|
||||
func createTargetObjectDetails(nameText string, layout model.ObjectTypeLayout) *types.Struct {
|
||||
fields := map[string]*types.Value{
|
||||
bundle.RelationKeyLayout.String(): pbtypes.Int64(int64(layout)),
|
||||
}
|
||||
|
||||
func createTargetObjectDetails(nameText string, layout model.ObjectTypeLayout) *domain.Details {
|
||||
details := domain.NewDetails()
|
||||
details.SetInt64(bundle.RelationKeyLayout, int64(layout))
|
||||
// Without this check title will be duplicated in template.WithNameToFirstBlock
|
||||
if layout != model.ObjectType_note {
|
||||
fields[bundle.RelationKeyName.String()] = pbtypes.String(nameText)
|
||||
details.SetString(bundle.RelationKeyName, nameText)
|
||||
}
|
||||
|
||||
details := &types.Struct{Fields: fields}
|
||||
return details
|
||||
}
|
||||
|
||||
|
@ -257,5 +252,5 @@ func copySubtreeOfBlocks(s *state.State, oldRootId string, oldBlocks []simple.Bl
|
|||
}
|
||||
|
||||
func hasNoteLayout(s *state.State) bool {
|
||||
return model.ObjectTypeLayout(pbtypes.GetInt64(s.Details(), bundle.RelationKeyLayout.String())) == model.ObjectType_note
|
||||
return model.ObjectTypeLayout(s.Details().GetInt64(bundle.RelationKeyLayout)) == model.ObjectType_note
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
|
@ -23,7 +22,6 @@ import (
|
|||
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
|
@ -35,7 +33,7 @@ func (tc testCreator) Add(object *smarttest.SmartTest) {
|
|||
tc.objects[object.Id()] = object
|
||||
}
|
||||
|
||||
func (tc testCreator) CreateSmartBlockFromState(_ context.Context, _ string, _ []domain.TypeKey, createState *state.State) (id string, newDetails *types.Struct, err error) {
|
||||
func (tc testCreator) CreateSmartBlockFromState(_ context.Context, _ string, _ []domain.TypeKey, createState *state.State) (id string, newdetails *domain.Details, err error) {
|
||||
id = bson.NewObjectId().Hex()
|
||||
object := smarttest.New(id)
|
||||
tc.objects[id] = object
|
||||
|
@ -54,7 +52,7 @@ func (tts testTemplateService) AddTemplate(id string, st *state.State) {
|
|||
tts.templates[id] = st
|
||||
}
|
||||
|
||||
func (tts testTemplateService) CreateTemplateStateWithDetails(id string, details *types.Struct) (st *state.State, err error) {
|
||||
func (tts testTemplateService) CreateTemplateStateWithDetails(id string, details *domain.Details) (st *state.State, err error) {
|
||||
if id == "" {
|
||||
st = state.NewDoc("", nil).NewState()
|
||||
template.InitTemplate(st, template.WithEmpty,
|
||||
|
@ -67,12 +65,12 @@ func (tts testTemplateService) CreateTemplateStateWithDetails(id string, details
|
|||
st = tts.templates[id]
|
||||
}
|
||||
templateDetails := st.Details()
|
||||
newDetails := pbtypes.StructMerge(templateDetails, details, false)
|
||||
newDetails := templateDetails.Merge(details)
|
||||
st.SetDetails(newDetails)
|
||||
return st, nil
|
||||
}
|
||||
|
||||
func (tts testTemplateService) CreateTemplateStateFromSmartBlock(sb smartblock.SmartBlock, details *types.Struct) *state.State {
|
||||
func (tts testTemplateService) CreateTemplateStateFromSmartBlock(sb smartblock.SmartBlock, details *domain.Details) *state.State {
|
||||
return tts.templates[sb.Id()]
|
||||
}
|
||||
|
||||
|
@ -106,14 +104,14 @@ func assertLinkedObjectHasTextBlocks(t *testing.T, ts testCreator, sourceObject
|
|||
assertHasTextBlocks(t, object, texts)
|
||||
}
|
||||
|
||||
func assertDetails(t *testing.T, id string, ts testCreator, details *types.Struct) {
|
||||
func assertDetails(t *testing.T, id string, ts testCreator, details *domain.Details) {
|
||||
object, ok := ts.objects[id]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
objDetails := object.Details()
|
||||
for key, value := range details.Fields {
|
||||
assert.Equal(t, value, objDetails.Fields[key])
|
||||
for key, value := range details.Iterate() {
|
||||
assert.Equal(t, value, objDetails.Get(key))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,11 +132,11 @@ func TestExtractObjects(t *testing.T) {
|
|||
return sb
|
||||
}
|
||||
|
||||
templateDetails := []*model.Detail{
|
||||
{Key: bundle.RelationKeyName.String(), Value: pbtypes.String("template")},
|
||||
{Key: bundle.RelationKeyIconImage.String(), Value: pbtypes.String("very funny img")},
|
||||
{Key: bundle.RelationKeyFeaturedRelations.String(), Value: pbtypes.StringList([]string{"tag", "type", "status"})},
|
||||
{Key: bundle.RelationKeyCoverId.String(), Value: pbtypes.String("poster with Van Damme")},
|
||||
templateDetails := []domain.Detail{
|
||||
{Key: bundle.RelationKeyName, Value: domain.String("template")},
|
||||
{Key: bundle.RelationKeyIconImage, Value: domain.String("very funny img")},
|
||||
{Key: bundle.RelationKeyFeaturedRelations, Value: domain.StringList([]string{"tag", "type", "status"})},
|
||||
{Key: bundle.RelationKeyCoverId, Value: domain.String("poster with Van Damme")},
|
||||
}
|
||||
|
||||
makeTemplateState := func(id string) *state.State {
|
||||
|
@ -158,7 +156,7 @@ func TestExtractObjects(t *testing.T) {
|
|||
typeKey string
|
||||
templateId string
|
||||
wantObjectsWithTexts [][]string
|
||||
wantDetails *types.Struct
|
||||
wantDetails *domain.Details
|
||||
}{
|
||||
{
|
||||
name: "undefined block",
|
||||
|
@ -216,7 +214,7 @@ func TestExtractObjects(t *testing.T) {
|
|||
"text 2.1",
|
||||
},
|
||||
},
|
||||
wantDetails: &types.Struct{},
|
||||
wantDetails: domain.NewDetails(),
|
||||
},
|
||||
{
|
||||
name: "two blocks, not all descendants present in requests",
|
||||
|
@ -248,12 +246,12 @@ func TestExtractObjects(t *testing.T) {
|
|||
"text 3", "text 3.1", "text 3.1.1",
|
||||
},
|
||||
},
|
||||
wantDetails: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String("text 3"),
|
||||
bundle.RelationKeyIconImage.String(): pbtypes.String("very funny img"),
|
||||
bundle.RelationKeyFeaturedRelations.String(): pbtypes.StringList([]string{"tag", "type", "status"}),
|
||||
bundle.RelationKeyCoverId.String(): pbtypes.String("poster with Van Damme"),
|
||||
}},
|
||||
wantDetails: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyName: domain.String("text 3"),
|
||||
bundle.RelationKeyIconImage: domain.String("very funny img"),
|
||||
bundle.RelationKeyFeaturedRelations: domain.StringList([]string{"tag", "type", "status"}),
|
||||
bundle.RelationKeyCoverId: domain.String("poster with Van Damme"),
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "two blocks with children, from template",
|
||||
|
@ -271,20 +269,20 @@ func TestExtractObjects(t *testing.T) {
|
|||
"text 3", "text 3.1", "text 3.1.1",
|
||||
},
|
||||
},
|
||||
wantDetails: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyIconImage.String(): pbtypes.String("very funny img"),
|
||||
bundle.RelationKeyFeaturedRelations.String(): pbtypes.StringList([]string{"tag", "type", "status"}),
|
||||
bundle.RelationKeyCoverId.String(): pbtypes.String("poster with Van Damme"),
|
||||
}},
|
||||
wantDetails: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyIconImage: domain.String("very funny img"),
|
||||
bundle.RelationKeyFeaturedRelations: domain.StringList([]string{"tag", "type", "status"}),
|
||||
bundle.RelationKeyCoverId: domain.String("poster with Van Damme"),
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "if target layout includes title, root is not added",
|
||||
blockIds: []string{"1.1"},
|
||||
typeKey: bundle.TypeKeyTask.String(),
|
||||
wantObjectsWithTexts: [][]string{{"text 1.1.1"}},
|
||||
wantDetails: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String("1.1"),
|
||||
}},
|
||||
wantDetails: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyName: domain.String("1.1"),
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "template and source are the same objects",
|
||||
|
@ -336,7 +334,7 @@ func TestExtractObjects(t *testing.T) {
|
|||
require.Len(t, linkIds, len(tc.wantObjectsWithTexts))
|
||||
for i, wantTexts := range tc.wantObjectsWithTexts {
|
||||
assertLinkedObjectHasTextBlocks(t, creator, sb, linkIds[i], wantTexts)
|
||||
if tc.wantDetails != nil && tc.wantDetails.Fields != nil {
|
||||
if tc.wantDetails != nil {
|
||||
assertDetails(t, linkIds[i], creator, tc.wantDetails)
|
||||
}
|
||||
}
|
||||
|
@ -344,15 +342,15 @@ func TestExtractObjects(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("do not add relation name - when creating note", func(t *testing.T) {
|
||||
fields := createTargetObjectDetails("whatever name", model.ObjectType_note).Fields
|
||||
details := createTargetObjectDetails("whatever name", model.ObjectType_note)
|
||||
|
||||
assert.NotContains(t, fields, bundle.RelationKeyName.String())
|
||||
assert.False(t, details.Has(bundle.RelationKeyName))
|
||||
})
|
||||
|
||||
t.Run("add relation name - when creating not note", func(t *testing.T) {
|
||||
fields := createTargetObjectDetails("whatever name", model.ObjectType_basic).Fields
|
||||
details := createTargetObjectDetails("whatever name", model.ObjectType_basic)
|
||||
|
||||
assert.Contains(t, fields, bundle.RelationKeyName.String())
|
||||
assert.True(t, details.Has(bundle.RelationKeyName))
|
||||
})
|
||||
t.Run("add custom link block", func(t *testing.T) {
|
||||
fixture := newFixture(t)
|
||||
|
@ -621,14 +619,14 @@ func newFixture(t *testing.T) *fixture {
|
|||
|
||||
objectStore.AddObjects(t, []spaceindex.TestObject{
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("id1"),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String("ot-note"),
|
||||
bundle.RelationKeyRecommendedLayout: pbtypes.Int64(int64(model.ObjectType_note)),
|
||||
bundle.RelationKeyId: domain.String("id1"),
|
||||
bundle.RelationKeyUniqueKey: domain.String("ot-note"),
|
||||
bundle.RelationKeyRecommendedLayout: domain.Int64(int64(model.ObjectType_note)),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("id2"),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String("ot-task"),
|
||||
bundle.RelationKeyRecommendedLayout: pbtypes.Int64(int64(model.ObjectType_todo)),
|
||||
bundle.RelationKeyId: domain.String("id2"),
|
||||
bundle.RelationKeyUniqueKey: domain.String("ot-task"),
|
||||
bundle.RelationKeyRecommendedLayout: domain.Int64(int64(model.ObjectType_todo)),
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
type IHistory interface {
|
||||
|
@ -50,7 +49,7 @@ func (h *history) Undo(ctx session.Context) (info HistoryInfo, err error) {
|
|||
}
|
||||
|
||||
if action.Details != nil {
|
||||
s.SetDetails(pbtypes.CopyStruct(action.Details.Before, false))
|
||||
s.SetDetails(action.Details.Before.Copy())
|
||||
}
|
||||
if err = h.Apply(s, smartblock.NoHistory, smartblock.NoRestrictions); err != nil {
|
||||
return
|
||||
|
@ -82,7 +81,7 @@ func (h *history) Redo(ctx session.Context) (info HistoryInfo, err error) {
|
|||
s.SetObjectTypeKeys(ot)
|
||||
}
|
||||
if action.Details != nil {
|
||||
s.SetDetails(pbtypes.CopyStruct(action.Details.After, true))
|
||||
s.SetDetails(action.Details.After.Copy())
|
||||
}
|
||||
if err = h.Apply(s, smartblock.NoHistory, smartblock.NoRestrictions); err != nil {
|
||||
return
|
||||
|
|
|
@ -4,29 +4,25 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func TestHistory_Undo(t *testing.T) {
|
||||
t.Run("basic", func(t *testing.T) {
|
||||
bDetails := &types.Struct{
|
||||
Fields: map[string]*types.Value{
|
||||
"beforeK": pbtypes.String("beforeV"),
|
||||
},
|
||||
}
|
||||
aDetails := &types.Struct{
|
||||
Fields: map[string]*types.Value{
|
||||
"afterK": pbtypes.String("afterV"),
|
||||
},
|
||||
}
|
||||
bDetails := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
"beforeK": domain.String("beforeV"),
|
||||
})
|
||||
|
||||
aDetails := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
"afterK": domain.String("afterV"),
|
||||
})
|
||||
sb := smarttest.New("test")
|
||||
sb.AddBlock(simple.New(&model.Block{Id: "test", ChildrenIds: []string{"2"}})).
|
||||
AddBlock(simple.New(&model.Block{Id: "2"}))
|
||||
|
@ -55,7 +51,7 @@ func TestHistory_Undo(t *testing.T) {
|
|||
s.Unlink("3")
|
||||
require.NoError(t, s.InsertTo("2", model.Block_Right, "3"))
|
||||
require.NoError(t, sb.Apply(s))
|
||||
//t.Log(sb.Doc.(*state.State).String())
|
||||
// t.Log(sb.Doc.(*state.State).String())
|
||||
|
||||
s = sb.NewState()
|
||||
s.Unlink("3")
|
||||
|
@ -66,7 +62,7 @@ func TestHistory_Undo(t *testing.T) {
|
|||
|
||||
_, err := h.Undo(nil)
|
||||
require.NoError(t, err)
|
||||
//t.Log(sb.Doc.(*state.State).String())
|
||||
// t.Log(sb.Doc.(*state.State).String())
|
||||
require.Len(t, sb.Doc.Pick("test").Model().ChildrenIds, 1)
|
||||
assert.True(t, strings.HasPrefix(sb.Doc.Pick("test").Model().ChildrenIds[0], "r-"))
|
||||
})
|
||||
|
|
|
@ -5,13 +5,13 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
bookmarksvc "github.com/anyproto/anytype-heart/core/block/bookmark"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/bookmark"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/domain/objectorigin"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
|
@ -41,7 +41,7 @@ type Bookmark interface {
|
|||
}
|
||||
|
||||
type BookmarkService interface {
|
||||
CreateBookmarkObject(ctx context.Context, spaceID string, details *types.Struct, getContent bookmarksvc.ContentFuture) (objectId string, newDetails *types.Struct, err error)
|
||||
CreateBookmarkObject(ctx context.Context, spaceID string, details *domain.Details, getContent bookmarksvc.ContentFuture) (objectId string, newDetails *domain.Details, err error)
|
||||
FetchAsync(spaceID string, blockID string, params bookmark.FetchParams)
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ func (s *storeObject) Init(ctx *smartblock.InitContext) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.subscription = newSubscription(s.Id(), s.eventSender)
|
||||
s.subscription = newSubscription(s.SpaceID(), s.Id(), s.eventSender)
|
||||
|
||||
stateStore, err := storestate.New(ctx.Ctx, s.Id(), s.crdtDb, ChatHandler{
|
||||
subscription: s.subscription,
|
||||
|
@ -322,11 +322,7 @@ func (s *storeObject) SubscribeLastMessages(ctx context.Context, limit int) ([]*
|
|||
return messages[i].OrderId < messages[j].OrderId
|
||||
})
|
||||
|
||||
var firstOrderId string
|
||||
if len(messages) > 0 {
|
||||
firstOrderId = messages[0].OrderId
|
||||
}
|
||||
s.subscription.subscribe(firstOrderId)
|
||||
s.subscription.enable()
|
||||
|
||||
return messages, 0, nil
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
)
|
||||
|
||||
type subscription struct {
|
||||
spaceId string
|
||||
chatId string
|
||||
eventSender event.Sender
|
||||
|
||||
|
@ -17,19 +18,18 @@ type subscription struct {
|
|||
|
||||
eventsBuffer []*pb.EventMessage
|
||||
|
||||
firstOrderId string
|
||||
enabled bool
|
||||
enabled bool
|
||||
}
|
||||
|
||||
func newSubscription(chatId string, eventSender event.Sender) *subscription {
|
||||
func newSubscription(spaceId string, chatId string, eventSender event.Sender) *subscription {
|
||||
return &subscription{
|
||||
spaceId: spaceId,
|
||||
chatId: chatId,
|
||||
eventSender: eventSender,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *subscription) subscribe(firstOrderId string) {
|
||||
s.firstOrderId = firstOrderId
|
||||
func (s *subscription) enable() {
|
||||
s.enabled = true
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ func (s *subscription) flush() {
|
|||
}
|
||||
|
||||
func (s *subscription) add(message *model.ChatMessage) {
|
||||
if !s.canSend(message) {
|
||||
if !s.canSend() {
|
||||
return
|
||||
}
|
||||
ev := &pb.EventChatAdd{
|
||||
|
@ -71,63 +71,52 @@ func (s *subscription) add(message *model.ChatMessage) {
|
|||
Message: message,
|
||||
OrderId: message.OrderId,
|
||||
}
|
||||
s.eventsBuffer = append(s.eventsBuffer, &pb.EventMessage{
|
||||
Value: &pb.EventMessageValueOfChatAdd{
|
||||
ChatAdd: ev,
|
||||
},
|
||||
})
|
||||
s.eventsBuffer = append(s.eventsBuffer, event.NewMessage(s.spaceId, &pb.EventMessageValueOfChatAdd{
|
||||
ChatAdd: ev,
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *subscription) delete(messageId string) {
|
||||
ev := &pb.EventChatDelete{
|
||||
Id: messageId,
|
||||
}
|
||||
s.eventsBuffer = append(s.eventsBuffer, &pb.EventMessage{
|
||||
Value: &pb.EventMessageValueOfChatDelete{
|
||||
ChatDelete: ev,
|
||||
},
|
||||
})
|
||||
s.eventsBuffer = append(s.eventsBuffer, event.NewMessage(s.spaceId, &pb.EventMessageValueOfChatDelete{
|
||||
ChatDelete: ev,
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *subscription) updateFull(message *model.ChatMessage) {
|
||||
if !s.canSend(message) {
|
||||
if !s.canSend() {
|
||||
return
|
||||
}
|
||||
ev := &pb.EventChatUpdate{
|
||||
Id: message.Id,
|
||||
Message: message,
|
||||
}
|
||||
s.eventsBuffer = append(s.eventsBuffer, &pb.EventMessage{
|
||||
Value: &pb.EventMessageValueOfChatUpdate{
|
||||
ChatUpdate: ev,
|
||||
},
|
||||
})
|
||||
s.eventsBuffer = append(s.eventsBuffer, event.NewMessage(s.spaceId, &pb.EventMessageValueOfChatUpdate{
|
||||
ChatUpdate: ev,
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *subscription) updateReactions(message *model.ChatMessage) {
|
||||
if !s.canSend(message) {
|
||||
if !s.canSend() {
|
||||
return
|
||||
}
|
||||
ev := &pb.EventChatUpdateReactions{
|
||||
Id: message.Id,
|
||||
Reactions: message.Reactions,
|
||||
}
|
||||
s.eventsBuffer = append(s.eventsBuffer, &pb.EventMessage{
|
||||
Value: &pb.EventMessageValueOfChatUpdateReactions{
|
||||
ChatUpdateReactions: ev,
|
||||
},
|
||||
})
|
||||
s.eventsBuffer = append(s.eventsBuffer, event.NewMessage(s.spaceId, &pb.EventMessageValueOfChatUpdateReactions{
|
||||
ChatUpdateReactions: ev,
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *subscription) canSend(message *model.ChatMessage) bool {
|
||||
func (s *subscription) canSend() bool {
|
||||
if s.sessionContext != nil {
|
||||
return true
|
||||
}
|
||||
if !s.enabled {
|
||||
return false
|
||||
}
|
||||
if s.firstOrderId > message.OrderId {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -448,13 +448,13 @@ func (cb *clipboard) pasteAny(
|
|||
}
|
||||
|
||||
relationLinks := destState.GetRelationLinks()
|
||||
var missingRelationKeys []string
|
||||
var missingRelationKeys []domain.RelationKey
|
||||
|
||||
// collect missing relation keys to add it to state
|
||||
for _, b := range s.Blocks() {
|
||||
if r := b.GetRelation(); r != nil {
|
||||
if !relationLinks.Has(r.Key) {
|
||||
missingRelationKeys = append(missingRelationKeys, r.Key)
|
||||
missingRelationKeys = append(missingRelationKeys, domain.RelationKey(r.Key))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -570,9 +570,9 @@ func (cb *clipboard) addRelationLinksToDataview(d *model.BlockContentDataview) (
|
|||
return
|
||||
}
|
||||
|
||||
relationKeysList := make([]string, len(relationKeys))
|
||||
relationKeysList := make([]domain.RelationKey, 0, len(relationKeys))
|
||||
for k := range relationKeys {
|
||||
relationKeysList = append(relationKeysList, k)
|
||||
relationKeysList = append(relationKeysList, domain.RelationKey(k))
|
||||
}
|
||||
relations, err := cb.objectStore.FetchRelationByKeys(relationKeysList...)
|
||||
if err != nil {
|
||||
|
|
|
@ -547,7 +547,7 @@ func TestClipboard_TitleOps(t *testing.T) {
|
|||
s.Add(tb)
|
||||
s.InsertTo("", 0, tb.Model().Id)
|
||||
}
|
||||
_, _, err := state.ApplyState(s, false)
|
||||
_, _, err := state.ApplyState("", s, false)
|
||||
require.NoError(t, err)
|
||||
return sb
|
||||
}
|
||||
|
@ -572,7 +572,7 @@ func TestClipboard_TitleOps(t *testing.T) {
|
|||
bm.Model().Id = "bookmarkId"
|
||||
s.Add(bm)
|
||||
s.InsertTo("", 0, bm.Model().Id)
|
||||
_, _, err := state.ApplyState(s, false)
|
||||
_, _, err := state.ApplyState("", s, false)
|
||||
require.NoError(t, err)
|
||||
return sb
|
||||
}
|
||||
|
@ -1103,7 +1103,7 @@ func addDescription(st *smarttest.SmartTest, description string) {
|
|||
newState := st.Doc.NewState()
|
||||
template.InitTemplate(newState, template.WithForcedDescription)
|
||||
newState.Get(template.DescriptionBlockId).(text.Block).SetText(description, nil)
|
||||
state.ApplyState(newState, false)
|
||||
state.ApplyState("", newState, false)
|
||||
}
|
||||
|
||||
func addRelations(st *smarttest.SmartTest) {
|
||||
|
@ -1111,7 +1111,7 @@ func addRelations(st *smarttest.SmartTest) {
|
|||
template.InitTemplate(newState, template.RequireHeader)
|
||||
template.InitTemplate(newState, template.WithFeaturedRelations)
|
||||
template.InitTemplate(newState, template.WithForcedDescription)
|
||||
state.ApplyState(newState, false)
|
||||
state.ApplyState("", newState, false)
|
||||
}
|
||||
|
||||
func TestClipboard_PasteToCodeBlock(t *testing.T) {
|
||||
|
|
|
@ -5,10 +5,10 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/anyproto/any-sync/app/ocache"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
)
|
||||
|
@ -26,7 +26,7 @@ type Collection interface {
|
|||
GetIds() (ids []string, err error)
|
||||
ModifyLocalDetails(
|
||||
objectId string,
|
||||
modifier func(current *types.Struct) (*types.Struct, error),
|
||||
modifier func(current *domain.Details) (*domain.Details, error),
|
||||
) (err error)
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ func (p *objectLinksCollection) GetIds() (ids []string, err error) {
|
|||
// and if it is not found, sets pending details in object store
|
||||
func (p *objectLinksCollection) ModifyLocalDetails(
|
||||
objectId string,
|
||||
modifier func(current *types.Struct) (*types.Struct, error),
|
||||
modifier func(current *domain.Details) (*domain.Details, error),
|
||||
) (err error) {
|
||||
if modifier == nil {
|
||||
return fmt.Errorf("modifier is nil")
|
||||
|
@ -126,7 +126,7 @@ func (p *objectLinksCollection) ModifyLocalDetails(
|
|||
return err
|
||||
}
|
||||
err = p.Space().Do(objectId, func(b smartblock.SmartBlock) error {
|
||||
// we just need to invoke the smartblock so it reads from pending details
|
||||
// we just need to invoke the smartblock, so it reads from pending details
|
||||
// no need to call modify twice
|
||||
if err == nil {
|
||||
return b.Apply(b.NewState())
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/spacecore/typeprovider"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
|
@ -135,7 +134,7 @@ func (c *layoutConverter) fromNoteToSet(st *state.State) error {
|
|||
}
|
||||
|
||||
func (c *layoutConverter) fromAnyToSet(st *state.State) error {
|
||||
source := pbtypes.GetStringList(st.Details(), bundle.RelationKeySetOf.String())
|
||||
source := st.Details().GetStringList(bundle.RelationKeySetOf)
|
||||
addFeaturedRelationSetOf(st)
|
||||
|
||||
dvBlock, err := dataview.BlockBySource(c.objectStore.SpaceIndex(st.SpaceID()), source)
|
||||
|
@ -147,11 +146,11 @@ func (c *layoutConverter) fromAnyToSet(st *state.State) error {
|
|||
}
|
||||
|
||||
func addFeaturedRelationSetOf(st *state.State) {
|
||||
fr := pbtypes.GetStringList(st.Details(), bundle.RelationKeyFeaturedRelations.String())
|
||||
fr := st.Details().GetStringList(bundle.RelationKeyFeaturedRelations)
|
||||
if !slices.Contains(fr, bundle.RelationKeySetOf.String()) {
|
||||
fr = append(fr, bundle.RelationKeySetOf.String())
|
||||
}
|
||||
st.SetDetail(bundle.RelationKeyFeaturedRelations.String(), pbtypes.StringList(fr))
|
||||
st.SetDetail(bundle.RelationKeyFeaturedRelations, domain.StringList(fr))
|
||||
}
|
||||
|
||||
func (c *layoutConverter) fromSetToCollection(st *state.State) error {
|
||||
|
@ -160,7 +159,7 @@ func (c *layoutConverter) fromSetToCollection(st *state.State) error {
|
|||
return fmt.Errorf("dataview block is not found")
|
||||
}
|
||||
details := st.Details()
|
||||
setSourceIds := pbtypes.GetStringList(details, bundle.RelationKeySetOf.String())
|
||||
setSourceIds := details.GetStringList(bundle.RelationKeySetOf)
|
||||
spaceId := st.SpaceID()
|
||||
|
||||
c.removeRelationSetOf(st)
|
||||
|
@ -194,7 +193,7 @@ func (c *layoutConverter) listIDsFromSet(spaceID string, typesFromSet []string)
|
|||
}
|
||||
ids := make([]string, 0, len(records))
|
||||
for _, record := range records {
|
||||
ids = append(ids, pbtypes.GetString(record.Details, bundle.RelationKeyId.String()))
|
||||
ids = append(ids, record.Details.GetString(bundle.RelationKeyId))
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
@ -218,9 +217,9 @@ func (c *layoutConverter) fromAnyToCollection(st *state.State) error {
|
|||
}
|
||||
|
||||
func (c *layoutConverter) fromNoteToAny(st *state.State) error {
|
||||
name, ok := st.Details().Fields[bundle.RelationKeyName.String()]
|
||||
name, ok := st.Details().TryString(bundle.RelationKeyName)
|
||||
|
||||
if !ok || name.GetStringValue() == "" {
|
||||
if !ok || name == "" {
|
||||
textBlock, err := getFirstTextBlock(st)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -228,7 +227,7 @@ func (c *layoutConverter) fromNoteToAny(st *state.State) error {
|
|||
if textBlock == nil {
|
||||
return nil
|
||||
}
|
||||
st.SetDetail(bundle.RelationKeyName.String(), pbtypes.String(textBlock.Model().GetText().GetText()))
|
||||
st.SetDetail(bundle.RelationKeyName, domain.String(textBlock.Model().GetText().GetText()))
|
||||
|
||||
for _, id := range textBlock.Model().ChildrenIds {
|
||||
st.Unlink(id)
|
||||
|
@ -252,11 +251,11 @@ func (c *layoutConverter) fromAnyToNote(st *state.State) error {
|
|||
}
|
||||
|
||||
func (c *layoutConverter) removeRelationSetOf(st *state.State) {
|
||||
st.RemoveDetail(bundle.RelationKeySetOf.String())
|
||||
st.RemoveDetail(bundle.RelationKeySetOf)
|
||||
|
||||
fr := pbtypes.GetStringList(st.Details(), bundle.RelationKeyFeaturedRelations.String())
|
||||
fr := st.Details().GetStringList(bundle.RelationKeyFeaturedRelations)
|
||||
fr = slice.RemoveMut(fr, bundle.RelationKeySetOf.String())
|
||||
st.SetDetail(bundle.RelationKeyFeaturedRelations.String(), pbtypes.StringList(fr))
|
||||
st.SetDetail(bundle.RelationKeyFeaturedRelations, domain.StringList(fr))
|
||||
}
|
||||
|
||||
func getFirstTextBlock(st *state.State) (simple.Block, error) {
|
||||
|
@ -274,8 +273,8 @@ func getFirstTextBlock(st *state.State) (simple.Block, error) {
|
|||
return res, nil
|
||||
}
|
||||
|
||||
func (c *layoutConverter) generateFilters(spaceId string, typesAndRelations []string) ([]*model.BlockContentDataviewFilter, error) {
|
||||
var filters []*model.BlockContentDataviewFilter
|
||||
func (c *layoutConverter) generateFilters(spaceId string, typesAndRelations []string) ([]database.FilterRequest, error) {
|
||||
var filters []database.FilterRequest
|
||||
m, err := c.sbtProvider.PartitionIDsByType(spaceId, typesAndRelations)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("partition ids by sb type: %w", err)
|
||||
|
@ -288,26 +287,26 @@ func (c *layoutConverter) generateFilters(spaceId string, typesAndRelations []st
|
|||
return filters, nil
|
||||
}
|
||||
|
||||
func (c *layoutConverter) appendRelationFilters(spaceId string, relationIDs []string, filters []*model.BlockContentDataviewFilter) ([]*model.BlockContentDataviewFilter, error) {
|
||||
func (c *layoutConverter) appendRelationFilters(spaceId string, relationIDs []string, filters []database.FilterRequest) ([]database.FilterRequest, error) {
|
||||
for _, relationID := range relationIDs {
|
||||
relation, err := c.objectStore.SpaceIndex(spaceId).GetRelationById(relationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get relation by id %s: %w", relationID, err)
|
||||
}
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{
|
||||
RelationKey: relation.Key,
|
||||
filters = append(filters, database.FilterRequest{
|
||||
RelationKey: domain.RelationKey(relation.Key),
|
||||
Condition: model.BlockContentDataviewFilter_Exists,
|
||||
})
|
||||
}
|
||||
return filters, nil
|
||||
}
|
||||
|
||||
func (c *layoutConverter) appendTypesFilter(types []string, filters []*model.BlockContentDataviewFilter) []*model.BlockContentDataviewFilter {
|
||||
func (c *layoutConverter) appendTypesFilter(types []string, filters []database.FilterRequest) []database.FilterRequest {
|
||||
if len(types) != 0 {
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{
|
||||
RelationKey: bundle.RelationKeyType.String(),
|
||||
filters = append(filters, database.FilterRequest{
|
||||
RelationKey: bundle.RelationKeyType,
|
||||
Condition: model.BlockContentDataviewFilter_In,
|
||||
Value: pbtypes.StringList(types),
|
||||
Value: domain.StringList(types),
|
||||
})
|
||||
}
|
||||
return filters
|
||||
|
|
|
@ -4,18 +4,17 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/template"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -26,9 +25,9 @@ const (
|
|||
func TestLayoutConverter_Convert(t *testing.T) {
|
||||
store := objectstore.NewStoreFixture(t)
|
||||
store.AddObjects(t, spaceId, []spaceindex.TestObject{{
|
||||
bundle.RelationKeyId: pbtypes.String(bundle.TypeKeyTask.URL()),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String(bundle.TypeKeyTask.URL()),
|
||||
bundle.RelationKeyId: domain.String(bundle.TypeKeyTask.URL()),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyUniqueKey: domain.String(bundle.TypeKeyTask.URL()),
|
||||
}})
|
||||
|
||||
for _, from := range []model.ObjectTypeLayout{
|
||||
|
@ -43,12 +42,10 @@ func TestLayoutConverter_Convert(t *testing.T) {
|
|||
st := state.NewDoc(root, map[string]simple.Block{
|
||||
root: simple.New(&model.Block{Id: root, ChildrenIds: []string{}}),
|
||||
}).NewState()
|
||||
st.SetDetails(&types.Struct{
|
||||
Fields: map[string]*types.Value{
|
||||
bundle.RelationKeySpaceId.String(): pbtypes.String(spaceId),
|
||||
bundle.RelationKeySetOf.String(): pbtypes.StringList([]string{bundle.TypeKeyTask.URL()}),
|
||||
},
|
||||
})
|
||||
st.SetDetails(domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeySetOf: domain.StringList([]string{bundle.TypeKeyTask.URL()}),
|
||||
}))
|
||||
|
||||
lc := layoutConverter{objectStore: store}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
|
||||
"github.com/anyproto/any-sync/commonspace/spacestorage"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/basic"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/collection"
|
||||
|
@ -19,7 +18,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/database"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
|
@ -64,7 +62,7 @@ func (p *Dashboard) CreationStateMigration(ctx *smartblock.InitContext) migratio
|
|||
template.WithDetailName("Home"),
|
||||
template.WithDetailIconEmoji("🏠"),
|
||||
template.WithNoDuplicateLinks(),
|
||||
template.WithForcedDetail(bundle.RelationKeyIsHidden, pbtypes.Bool(true)),
|
||||
template.WithForcedDetail(bundle.RelationKeyIsHidden, domain.Bool(true)),
|
||||
)
|
||||
},
|
||||
}
|
||||
|
@ -73,7 +71,7 @@ func (p *Dashboard) CreationStateMigration(ctx *smartblock.InitContext) migratio
|
|||
func (p *Dashboard) StateMigrations() migration.Migrations {
|
||||
return migration.MakeMigrations([]migration.Migration{{
|
||||
Version: 2,
|
||||
Proc: template.WithForcedDetail(bundle.RelationKeyIsHidden, pbtypes.Bool(true)),
|
||||
Proc: template.WithForcedDetail(bundle.RelationKeyIsHidden, domain.Bool(true)),
|
||||
}})
|
||||
}
|
||||
|
||||
|
@ -94,11 +92,11 @@ func (p *Dashboard) updateObjects(info smartblock.ApplyInfo) (err error) {
|
|||
|
||||
func (p *Dashboard) updateInStore(favoritedIds []string) error {
|
||||
records, err := p.objectStore.Query(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
RelationKey: bundle.RelationKeyIsFavorite.String(),
|
||||
RelationKey: bundle.RelationKeyIsFavorite,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
Value: domain.Bool(true),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -107,19 +105,17 @@ func (p *Dashboard) updateInStore(favoritedIds []string) error {
|
|||
}
|
||||
var storeFavoritedIds = make([]string, 0, len(records))
|
||||
for _, rec := range records {
|
||||
storeFavoritedIds = append(storeFavoritedIds, pbtypes.GetString(rec.Details, bundle.RelationKeyId.String()))
|
||||
storeFavoritedIds = append(storeFavoritedIds, rec.Details.GetString(bundle.RelationKeyId))
|
||||
}
|
||||
|
||||
removedIds, addedIds := slice.DifferenceRemovedAdded(storeFavoritedIds, favoritedIds)
|
||||
for _, removedId := range removedIds {
|
||||
go func(id string) {
|
||||
if err := p.ModifyLocalDetails(id, func(current *types.Struct) (*types.Struct, error) {
|
||||
if current == nil || current.Fields == nil {
|
||||
current = &types.Struct{
|
||||
Fields: map[string]*types.Value{},
|
||||
}
|
||||
if err := p.ModifyLocalDetails(id, func(current *domain.Details) (*domain.Details, error) {
|
||||
if current == nil {
|
||||
current = domain.NewDetails()
|
||||
}
|
||||
current.Fields[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(false)
|
||||
current.SetBool(bundle.RelationKeyIsFavorite, false)
|
||||
return current, nil
|
||||
}); err != nil {
|
||||
logFavoriteError(err)
|
||||
|
@ -128,13 +124,11 @@ func (p *Dashboard) updateInStore(favoritedIds []string) error {
|
|||
}
|
||||
for _, addedId := range addedIds {
|
||||
go func(id string) {
|
||||
if err := p.ModifyLocalDetails(id, func(current *types.Struct) (*types.Struct, error) {
|
||||
if current == nil || current.Fields == nil {
|
||||
current = &types.Struct{
|
||||
Fields: map[string]*types.Value{},
|
||||
}
|
||||
if err := p.ModifyLocalDetails(id, func(current *domain.Details) (*domain.Details, error) {
|
||||
if current == nil {
|
||||
current = domain.NewDetails()
|
||||
}
|
||||
current.Fields[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true)
|
||||
current.SetBool(bundle.RelationKeyIsFavorite, true)
|
||||
return current, nil
|
||||
}); err != nil {
|
||||
logFavoriteError(err)
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/logging"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/internalflag"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
|
@ -90,7 +89,7 @@ func (d *sdataview) SetSource(ctx session.Context, blockId string, source []stri
|
|||
|
||||
if len(source) == 0 {
|
||||
s.Unlink(blockId)
|
||||
s.SetLocalDetail(bundle.RelationKeySetOf.String(), pbtypes.StringList(source))
|
||||
s.SetLocalDetail(bundle.RelationKeySetOf, domain.StringList(source))
|
||||
return d.Apply(s, smartblock.NoRestrictions, smartblock.KeepInternalFlags)
|
||||
}
|
||||
|
||||
|
@ -108,7 +107,7 @@ func (d *sdataview) SetSource(ctx session.Context, blockId string, source []stri
|
|||
s.InsertTo("", 0, blockId)
|
||||
}
|
||||
|
||||
s.SetLocalDetail(bundle.RelationKeySetOf.String(), pbtypes.StringList(source))
|
||||
s.SetLocalDetail(bundle.RelationKeySetOf, domain.StringList(source))
|
||||
return d.Apply(s, smartblock.NoRestrictions, smartblock.KeepInternalFlags)
|
||||
}
|
||||
|
||||
|
@ -127,7 +126,7 @@ func (d *sdataview) SetSourceInSet(ctx session.Context, source []string) (err er
|
|||
return fmt.Errorf("failed to update view '%s' of set '%s': %w", view.Id, s.RootId(), err)
|
||||
}
|
||||
}
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeySetOf, pbtypes.StringList(source))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeySetOf, domain.StringList(source))
|
||||
|
||||
flags := internalflag.NewFromState(s)
|
||||
// set with source is no longer empty
|
||||
|
|
|
@ -13,12 +13,12 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/editor/template"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/dataview"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
|
@ -148,14 +148,14 @@ func TestDataview_SetSource(t *testing.T) {
|
|||
|
||||
fx.store.AddObjects(t, []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spcId),
|
||||
bundle.RelationKeyId: pbtypes.String("rel-id"),
|
||||
bundle.RelationKeyRelationKey: pbtypes.String("id"),
|
||||
bundle.RelationKeySpaceId: domain.String(spcId),
|
||||
bundle.RelationKeyId: domain.String("rel-id"),
|
||||
bundle.RelationKeyRelationKey: domain.String("id"),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spcId),
|
||||
bundle.RelationKeyId: pbtypes.String("rel-name"),
|
||||
bundle.RelationKeyRelationKey: pbtypes.String("name"),
|
||||
bundle.RelationKeySpaceId: domain.String(spcId),
|
||||
bundle.RelationKeyId: domain.String("rel-name"),
|
||||
bundle.RelationKeyRelationKey: domain.String("name"),
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -164,7 +164,7 @@ func TestDataview_SetSource(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
setOf := pbtypes.GetStringList(fx.sb.LocalDetails(), bundle.RelationKeySetOf.String())
|
||||
setOf := fx.sb.CombinedDetails().GetStringList(bundle.RelationKeySetOf)
|
||||
require.Len(t, setOf, 2)
|
||||
assert.True(t, slice.UnsortedEqual(setOf, source))
|
||||
|
||||
|
@ -181,9 +181,9 @@ func TestDataview_SetSource(t *testing.T) {
|
|||
fx.sb.AddBlock(simple.New(&model.Block{Id: "dv", Content: &model.BlockContentOfDataview{Dataview: &model.BlockContentDataview{
|
||||
Source: []string{"ot-bookmark"},
|
||||
}}}))
|
||||
err := fx.sb.SetDetails(nil, []*model.Detail{{
|
||||
Key: bundle.RelationKeySetOf.String(),
|
||||
Value: pbtypes.StringList([]string{"ot-bookmark"}),
|
||||
err := fx.sb.SetDetails(nil, []domain.Detail{{
|
||||
Key: bundle.RelationKeySetOf,
|
||||
Value: domain.StringList([]string{"ot-bookmark"}),
|
||||
}}, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -192,7 +192,7 @@ func TestDataview_SetSource(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
setOf := pbtypes.GetStringList(fx.sb.LocalDetails(), bundle.RelationKeySetOf.String())
|
||||
setOf := fx.sb.CombinedDetails().GetStringList(bundle.RelationKeySetOf)
|
||||
assert.Len(t, setOf, 0)
|
||||
|
||||
block := fx.sb.Pick("dv")
|
||||
|
@ -209,12 +209,12 @@ func TestDataview_SetSourceInSet(t *testing.T) {
|
|||
{DefaultObjectTypeId: "ot-note", DefaultTemplateId: "NoTe"},
|
||||
{DefaultObjectTypeId: "ot-task", DefaultTemplateId: "tAsK"},
|
||||
}}}}))
|
||||
err := fx.sb.SetDetails(nil, []*model.Detail{{
|
||||
Key: bundle.RelationKeySetOf.String(),
|
||||
Value: pbtypes.StringList([]string{"rel-name", "rel-id"}),
|
||||
err := fx.sb.SetDetails(nil, []domain.Detail{{
|
||||
Key: bundle.RelationKeySetOf,
|
||||
Value: domain.StringList([]string{"rel-name", "rel-id"}),
|
||||
}, {
|
||||
Key: bundle.RelationKeyInternalFlags.String(),
|
||||
Value: pbtypes.IntList(int(model.InternalFlag_editorDeleteEmpty)),
|
||||
Key: bundle.RelationKeyInternalFlags,
|
||||
Value: domain.Int64List([]int64{int64(model.InternalFlag_editorDeleteEmpty)}),
|
||||
}}, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -223,7 +223,7 @@ func TestDataview_SetSourceInSet(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
setOf := pbtypes.GetStringList(fx.sb.NewState().Details(), bundle.RelationKeySetOf.String())
|
||||
setOf := fx.sb.NewState().Details().GetStringList(bundle.RelationKeySetOf)
|
||||
require.Len(t, setOf, 1)
|
||||
assert.Equal(t, "ot-page", setOf[0])
|
||||
|
||||
|
@ -237,7 +237,7 @@ func TestDataview_SetSourceInSet(t *testing.T) {
|
|||
assert.Empty(t, dv.Views[1].DefaultTemplateId)
|
||||
assert.Empty(t, dv.Views[1].DefaultObjectTypeId)
|
||||
|
||||
assert.Empty(t, pbtypes.GetIntList(fx.sb.NewState().Details(), bundle.RelationKeyInternalFlags.String()))
|
||||
assert.Empty(t, fx.sb.NewState().Details().GetInt64List(bundle.RelationKeyInternalFlags))
|
||||
})
|
||||
|
||||
// TODO: GO-4189 Add more tests when more logic on SetSourceToSet will be added
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/process"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/file"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/domain/objectorigin"
|
||||
"github.com/anyproto/anytype-heart/core/files/fileuploader"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
|
@ -48,7 +49,7 @@ func NewFile(sb smartblock.SmartBlock, blockService BlockService, picker cache.O
|
|||
}
|
||||
|
||||
type BlockService interface {
|
||||
CreateLinkToTheNewObject(ctx context.Context, sctx session.Context, req *pb.RpcBlockLinkCreateWithObjectRequest) (linkID string, pageID string, details *types.Struct, err error)
|
||||
CreateLinkToTheNewObject(ctx context.Context, sctx session.Context, req *pb.RpcBlockLinkCreateWithObjectRequest) (linkID string, pageID string, details *domain.Details, err error)
|
||||
}
|
||||
|
||||
type File interface {
|
||||
|
@ -125,7 +126,7 @@ func (sf *sfile) SetFileTargetObjectId(ctx session.Context, blockId, targetObjec
|
|||
return err
|
||||
}
|
||||
var blockContentFileType model.BlockContentFileType
|
||||
switch model.ObjectTypeLayout(pbtypes.GetInt64(sb.Details(), bundle.RelationKeyLayout.String())) {
|
||||
switch model.ObjectTypeLayout(sb.Details().GetInt64(bundle.RelationKeyLayout)) {
|
||||
case model.ObjectType_image:
|
||||
blockContentFileType = model.BlockContentFile_Image
|
||||
case model.ObjectType_audio:
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/anyproto/any-sync/accountservice/mock_accountservice"
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/commonfile/fileservice"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -22,6 +21,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/editor/template"
|
||||
"github.com/anyproto/anytype-heart/core/block/process"
|
||||
"github.com/anyproto/anytype-heart/core/block/restriction"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/event/mock_event"
|
||||
"github.com/anyproto/anytype-heart/core/files"
|
||||
"github.com/anyproto/anytype-heart/core/files/fileobject/mock_fileobject"
|
||||
|
@ -40,7 +40,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/tests/blockbuilder"
|
||||
"github.com/anyproto/anytype-heart/tests/testutil"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
type fileFixture struct {
|
||||
|
@ -110,9 +109,9 @@ func TestFile(t *testing.T) {
|
|||
// given
|
||||
fx := newFixture(t)
|
||||
fileSb := smarttest.New("root")
|
||||
fileSb.SetDetails(nil, []*model.Detail{{
|
||||
Key: bundle.RelationKeyLayout.String(),
|
||||
Value: pbtypes.Int64(int64(testCase.typeLayout)),
|
||||
fileSb.SetDetails(nil, []domain.Detail{{
|
||||
Key: bundle.RelationKeyLayout,
|
||||
Value: domain.Int64(int64(testCase.typeLayout)),
|
||||
}}, false)
|
||||
|
||||
fx.pickerFx.EXPECT().GetObject(mock.Anything, "testObjId").Return(fileSb, nil)
|
||||
|
@ -161,12 +160,12 @@ func TestDropFiles(t *testing.T) {
|
|||
|
||||
fx := newFixture(t)
|
||||
st := fx.sb.Doc.NewState()
|
||||
st.SetDetail(bundle.RelationKeyLayout.String(), pbtypes.Int64(int64(model.ObjectType_collection)))
|
||||
st.SetDetail(bundle.RelationKeyLayout, domain.Int64(int64(model.ObjectType_collection)))
|
||||
fx.sb.Doc = st
|
||||
fx.pickerFx.EXPECT().GetObject(context.Background(), "root").Return(fx, nil).Maybe()
|
||||
fx.mockSender.EXPECT().Broadcast(mock.Anything).Return().Maybe()
|
||||
mockService := mock_fileobject.NewMockService(t)
|
||||
mockService.EXPECT().Create(mock.Anything, mock.Anything, mock.Anything).Return("fileObjectId", &types.Struct{Fields: map[string]*types.Value{}}, nil).Maybe()
|
||||
mockService.EXPECT().Create(mock.Anything, mock.Anything, mock.Anything).Return("fileObjectId", domain.NewDetails(), nil).Maybe()
|
||||
fx.fileUploaderFactory = prepareFileService(t, fx.mockSender, mockService)
|
||||
|
||||
// when
|
||||
|
@ -186,12 +185,12 @@ func TestDropFiles(t *testing.T) {
|
|||
|
||||
fx := newFixture(t)
|
||||
st := fx.sb.Doc.NewState()
|
||||
st.SetDetail(bundle.RelationKeyLayout.String(), pbtypes.Int64(int64(model.ObjectType_collection)))
|
||||
st.SetDetail(bundle.RelationKeyLayout, domain.Int64(int64(model.ObjectType_collection)))
|
||||
fx.sb.Doc = st
|
||||
fx.pickerFx.EXPECT().GetObject(context.Background(), "root").Return(fx, nil).Maybe()
|
||||
fx.mockSender.EXPECT().Broadcast(mock.Anything).Return().Maybe()
|
||||
mockService := mock_fileobject.NewMockService(t)
|
||||
mockService.EXPECT().Create(mock.Anything, mock.Anything, mock.Anything).Return("fileObjectId", &types.Struct{Fields: map[string]*types.Value{}}, nil).Maybe()
|
||||
mockService.EXPECT().Create(mock.Anything, mock.Anything, mock.Anything).Return("fileObjectId", domain.NewDetails(), nil).Maybe()
|
||||
fx.fileUploaderFactory = prepareFileService(t, fx.mockSender, mockService)
|
||||
|
||||
// when
|
||||
|
@ -211,12 +210,12 @@ func TestDropFiles(t *testing.T) {
|
|||
|
||||
fx := newFixture(t)
|
||||
st := fx.sb.Doc.NewState()
|
||||
st.SetDetail(bundle.RelationKeyLayout.String(), pbtypes.Int64(int64(model.ObjectType_collection)))
|
||||
st.SetDetail(bundle.RelationKeyLayout, domain.Int64(int64(model.ObjectType_collection)))
|
||||
fx.sb.Doc = st
|
||||
fx.pickerFx.EXPECT().GetObject(context.Background(), "root").Return(fx, nil)
|
||||
fx.mockSender.EXPECT().Broadcast(mock.Anything).Return()
|
||||
mockService := mock_fileobject.NewMockService(t)
|
||||
mockService.EXPECT().Create(context.Background(), "", mock.Anything).Return("fileObjectId", &types.Struct{Fields: map[string]*types.Value{}}, nil).Maybe()
|
||||
mockService.EXPECT().Create(context.Background(), "", mock.Anything).Return("fileObjectId", domain.NewDetails(), nil).Maybe()
|
||||
fx.fileUploaderFactory = prepareFileService(t, fx.mockSender, mockService)
|
||||
|
||||
// when
|
||||
|
@ -246,12 +245,12 @@ func TestDropFiles(t *testing.T) {
|
|||
|
||||
fx := newFixture(t)
|
||||
st := fx.sb.Doc.NewState()
|
||||
st.SetDetail(bundle.RelationKeyLayout.String(), pbtypes.Int64(int64(model.ObjectType_collection)))
|
||||
st.SetDetail(bundle.RelationKeyLayout, domain.Int64(int64(model.ObjectType_collection)))
|
||||
fx.sb.Doc = st
|
||||
fx.pickerFx.EXPECT().GetObject(context.Background(), "root").Return(fx, nil)
|
||||
fx.mockSender.EXPECT().Broadcast(mock.Anything).Return()
|
||||
mockService := mock_fileobject.NewMockService(t)
|
||||
mockService.EXPECT().Create(context.Background(), "", mock.Anything).Return("fileObjectId", &types.Struct{Fields: map[string]*types.Value{}}, nil).Maybe()
|
||||
mockService.EXPECT().Create(context.Background(), "", mock.Anything).Return("fileObjectId", domain.NewDetails(), nil).Maybe()
|
||||
fx.fileUploaderFactory = prepareFileService(t, fx.mockSender, mockService)
|
||||
|
||||
// when
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/basic"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
|
@ -108,10 +106,10 @@ func (f *File) InjectVirtualBlocks(objectId string, view *model.ObjectView) {
|
|||
return
|
||||
}
|
||||
|
||||
var details *types.Struct
|
||||
var details *domain.Details
|
||||
for _, det := range view.Details {
|
||||
if det.Id == objectId {
|
||||
details = det.Details
|
||||
details = domain.NewDetailsFromProto(det.Details)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/app/logger"
|
||||
"github.com/cheggaaa/mb/v3"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
|
@ -21,7 +20,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/space"
|
||||
"github.com/anyproto/anytype-heart/space/clientspace"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -174,14 +172,14 @@ func (u *updater) updateLastUsedDate(spc clientspace.Space, key Key, ts int64) e
|
|||
return fmt.Errorf("failed to get details: %w", err)
|
||||
}
|
||||
|
||||
id := pbtypes.GetString(details.Details, bundle.RelationKeyId.String())
|
||||
id := details.GetString(bundle.RelationKeyId)
|
||||
if id == "" {
|
||||
return fmt.Errorf("failed to get id from details: %w", err)
|
||||
}
|
||||
|
||||
if err = spc.DoCtx(u.ctx, id, func(sb smartblock.SmartBlock) error {
|
||||
st := sb.NewState()
|
||||
st.SetLocalDetail(bundle.RelationKeyLastUsedDate.String(), pbtypes.Int64(ts))
|
||||
st.SetLocalDetail(bundle.RelationKeyLastUsedDate, domain.Int64(ts))
|
||||
return sb.Apply(st)
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to set lastUsedDate to object: %w", err)
|
||||
|
@ -189,8 +187,8 @@ func (u *updater) updateLastUsedDate(spc clientspace.Space, key Key, ts int64) e
|
|||
return nil
|
||||
}
|
||||
|
||||
func SetLastUsedDateForInitialObjectType(id string, details *types.Struct) {
|
||||
if !strings.HasPrefix(id, addr.BundledObjectTypeURLPrefix) || details == nil || details.Fields == nil {
|
||||
func SetLastUsedDateForInitialObjectType(id string, details *domain.Details) {
|
||||
if !strings.HasPrefix(id, addr.BundledObjectTypeURLPrefix) || details == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -212,5 +210,5 @@ func SetLastUsedDateForInitialObjectType(id string, details *types.Struct) {
|
|||
|
||||
// we do this trick to order crucial Anytype object types by last date
|
||||
lastUsed := time.Now().Add(time.Duration(-1 * priority * int64(maxInstallationTime))).Unix()
|
||||
details.Fields[bundle.RelationKeyLastUsedDate.String()] = pbtypes.Int64(lastUsed)
|
||||
details.SetInt64(bundle.RelationKeyLastUsedDate, lastUsed)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -18,12 +17,11 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/space/clientspace"
|
||||
"github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func TestSetLastUsedDateForInitialType(t *testing.T) {
|
||||
isLastUsedDateGreater := func(details1, details2 *types.Struct) bool {
|
||||
return pbtypes.GetInt64(details1, bundle.RelationKeyLastUsedDate.String()) > pbtypes.GetInt64(details2, bundle.RelationKeyLastUsedDate.String())
|
||||
isLastUsedDateGreater := func(details1, details2 *domain.Details) bool {
|
||||
return details1.GetInt64(bundle.RelationKeyLastUsedDate) > details2.GetInt64(bundle.RelationKeyLastUsedDate)
|
||||
}
|
||||
|
||||
t.Run("object types are sorted by lastUsedDate in correct order", func(t *testing.T) {
|
||||
|
@ -40,11 +38,11 @@ func TestSetLastUsedDateForInitialType(t *testing.T) {
|
|||
rand.Shuffle(len(ots), func(i, j int) {
|
||||
ots[i], ots[j] = ots[j], ots[i]
|
||||
})
|
||||
detailMap := map[string]*types.Struct{}
|
||||
detailMap := map[string]*domain.Details{}
|
||||
|
||||
// when
|
||||
for _, id := range ots {
|
||||
details := &types.Struct{Fields: make(map[string]*types.Value)}
|
||||
details := domain.NewDetails()
|
||||
SetLastUsedDateForInitialObjectType(id, details)
|
||||
detailMap[id] = details
|
||||
}
|
||||
|
@ -64,31 +62,31 @@ func TestUpdateLastUsedDate(t *testing.T) {
|
|||
|
||||
ts := time.Now().Unix()
|
||||
|
||||
isLastUsedDateRecent := func(details *types.Struct, deltaSeconds int64) bool {
|
||||
return pbtypes.GetInt64(details, bundle.RelationKeyLastUsedDate.String())+deltaSeconds > time.Now().Unix()
|
||||
isLastUsedDateRecent := func(details *domain.Details, deltaSeconds int64) bool {
|
||||
return details.GetInt64(bundle.RelationKeyLastUsedDate)+deltaSeconds > time.Now().Unix()
|
||||
}
|
||||
|
||||
store := objectstore.NewStoreFixture(t)
|
||||
store.AddObjects(t, spaceId, []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String(bundle.RelationKeyCamera.URL()),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String(bundle.RelationKeyCamera.URL()),
|
||||
bundle.RelationKeyId: domain.String(bundle.RelationKeyCamera.URL()),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyUniqueKey: domain.String(bundle.RelationKeyCamera.URL()),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String(bundle.TypeKeyDiaryEntry.URL()),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String(bundle.TypeKeyDiaryEntry.URL()),
|
||||
bundle.RelationKeyId: domain.String(bundle.TypeKeyDiaryEntry.URL()),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyUniqueKey: domain.String(bundle.TypeKeyDiaryEntry.URL()),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("rel-custom"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String("rel-custom"),
|
||||
bundle.RelationKeyId: domain.String("rel-custom"),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyUniqueKey: domain.String("rel-custom"),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("opt-done"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String("opt-done"),
|
||||
bundle.RelationKeyId: domain.String("opt-done"),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceId),
|
||||
bundle.RelationKeyUniqueKey: domain.String("opt-done"),
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/database"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
var pageRequiredRelations = []domain.RelationKey{
|
||||
|
@ -102,7 +101,7 @@ func (p *Page) Init(ctx *smartblock.InitContext) (err error) {
|
|||
if p.isRelationDeleted(ctx) {
|
||||
// todo: move this to separate component
|
||||
go func() {
|
||||
err = p.deleteRelationOptions(p.SpaceID(), pbtypes.GetString(p.Details(), bundle.RelationKeyRelationKey.String()))
|
||||
err = p.deleteRelationOptions(p.SpaceID(), p.Details().GetString(bundle.RelationKeyRelationKey))
|
||||
if err != nil {
|
||||
log.With("err", err).Error("failed to delete relation options")
|
||||
}
|
||||
|
@ -113,21 +112,21 @@ func (p *Page) Init(ctx *smartblock.InitContext) (err error) {
|
|||
|
||||
func (p *Page) isRelationDeleted(ctx *smartblock.InitContext) bool {
|
||||
return p.Type() == coresb.SmartBlockTypeRelation &&
|
||||
pbtypes.GetBool(ctx.State.Details(), bundle.RelationKeyIsUninstalled.String())
|
||||
ctx.State.Details().GetBool(bundle.RelationKeyIsUninstalled)
|
||||
}
|
||||
|
||||
func (p *Page) deleteRelationOptions(spaceID string, relationKey string) error {
|
||||
relationOptions, _, err := p.objectStore.QueryObjectIds(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
RelationKey: bundle.RelationKeyRelationKey.String(),
|
||||
RelationKey: bundle.RelationKeyRelationKey,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(relationKey),
|
||||
Value: domain.String(relationKey),
|
||||
},
|
||||
{
|
||||
RelationKey: bundle.RelationKeyLayout.String(),
|
||||
RelationKey: bundle.RelationKeyLayout,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Int64(int64(model.ObjectType_relationOption)),
|
||||
Value: domain.Int64(model.ObjectType_relationOption),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -161,7 +160,7 @@ func (p *Page) CreationStateMigration(ctx *smartblock.InitContext) migration.Mig
|
|||
if err != nil {
|
||||
log.Errorf("failed to get object by unique key: %v", err)
|
||||
} else {
|
||||
layout = model.ObjectTypeLayout(pbtypes.GetInt64(otype.Details, bundle.RelationKeyRecommendedLayout.String()))
|
||||
layout = model.ObjectTypeLayout(otype.GetInt64(bundle.RelationKeyRecommendedLayout))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@ package editor
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/basic"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/template"
|
||||
|
@ -13,7 +11,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
var participantRequiredRelations = []domain.RelationKey{
|
||||
|
@ -49,11 +46,11 @@ func (p *participant) Init(ctx *smartblock.InitContext) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyIsReadonly, pbtypes.Bool(true))
|
||||
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyIsArchived, pbtypes.Bool(false))
|
||||
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyIsHidden, pbtypes.Bool(false))
|
||||
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyLayout, pbtypes.Int64(int64(model.ObjectType_participant)))
|
||||
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyLayoutAlign, pbtypes.Int64(int64(model.Block_AlignCenter)))
|
||||
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyIsReadonly, domain.Bool(true))
|
||||
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyIsArchived, domain.Bool(false))
|
||||
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyIsHidden, domain.Bool(false))
|
||||
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyLayout, domain.Int64(model.ObjectType_participant))
|
||||
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyLayoutAlign, domain.Int64(model.Block_AlignCenter))
|
||||
|
||||
records, err := p.objectStore.QueryByIds([]string{p.Id()})
|
||||
if err != nil {
|
||||
|
@ -73,23 +70,23 @@ func (p *participant) Init(ctx *smartblock.InitContext) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *participant) ModifyProfileDetails(profileDetails *types.Struct) (err error) {
|
||||
details := pbtypes.CopyStructFields(profileDetails,
|
||||
bundle.RelationKeyName.String(),
|
||||
bundle.RelationKeyDescription.String(),
|
||||
bundle.RelationKeyIconImage.String(),
|
||||
bundle.RelationKeyGlobalName.String())
|
||||
details.Fields[bundle.RelationKeyIdentityProfileLink.String()] = pbtypes.String(pbtypes.GetString(profileDetails, bundle.RelationKeyId.String()))
|
||||
func (p *participant) ModifyProfileDetails(profileDetails *domain.Details) (err error) {
|
||||
details := profileDetails.CopyOnlyKeys(
|
||||
bundle.RelationKeyName,
|
||||
bundle.RelationKeyDescription,
|
||||
bundle.RelationKeyIconImage,
|
||||
bundle.RelationKeyGlobalName,
|
||||
)
|
||||
details.SetString(bundle.RelationKeyIdentityProfileLink, profileDetails.GetString(bundle.RelationKeyId))
|
||||
return p.modifyDetails(details)
|
||||
}
|
||||
|
||||
func (p *participant) ModifyIdentityDetails(profile *model.IdentityProfile) (err error) {
|
||||
details := &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String(profile.Name),
|
||||
bundle.RelationKeyDescription.String(): pbtypes.String(profile.Description),
|
||||
bundle.RelationKeyIconImage.String(): pbtypes.String(profile.IconCid),
|
||||
bundle.RelationKeyGlobalName.String(): pbtypes.String(profile.GlobalName),
|
||||
}}
|
||||
details := domain.NewDetails()
|
||||
details.SetString(bundle.RelationKeyName, profile.Name)
|
||||
details.SetString(bundle.RelationKeyDescription, profile.Description)
|
||||
details.SetString(bundle.RelationKeyIconImage, profile.IconCid)
|
||||
details.SetString(bundle.RelationKeyGlobalName, profile.GlobalName)
|
||||
return p.modifyDetails(details)
|
||||
}
|
||||
|
||||
|
@ -102,9 +99,9 @@ func (p *participant) TryClose(objectTTL time.Duration) (bool, error) {
|
|||
return false, nil
|
||||
}
|
||||
|
||||
func (p *participant) modifyDetails(newDetails *types.Struct) (err error) {
|
||||
return p.DetailsUpdatable.UpdateDetails(func(current *types.Struct) (*types.Struct, error) {
|
||||
return pbtypes.StructMerge(current, newDetails, false), nil
|
||||
func (p *participant) modifyDetails(newDetails *domain.Details) (err error) {
|
||||
return p.DetailsUpdatable.UpdateDetails(func(current *domain.Details) (*domain.Details, error) {
|
||||
return current.Merge(newDetails), nil
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -114,14 +111,14 @@ func buildParticipantDetails(
|
|||
identity string,
|
||||
permissions model.ParticipantPermissions,
|
||||
status model.ParticipantStatus,
|
||||
) *types.Struct {
|
||||
return &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyId.String(): pbtypes.String(id),
|
||||
bundle.RelationKeyIdentity.String(): pbtypes.String(identity),
|
||||
bundle.RelationKeySpaceId.String(): pbtypes.String(spaceId),
|
||||
bundle.RelationKeyLastModifiedBy.String(): pbtypes.String(id),
|
||||
bundle.RelationKeyParticipantPermissions.String(): pbtypes.Int64(int64(permissions)),
|
||||
bundle.RelationKeyParticipantStatus.String(): pbtypes.Int64(int64(status)),
|
||||
bundle.RelationKeyIsHiddenDiscovery.String(): pbtypes.Bool(status != model.ParticipantStatus_Active),
|
||||
}}
|
||||
) *domain.Details {
|
||||
det := domain.NewDetails()
|
||||
det.SetString(bundle.RelationKeyId, id)
|
||||
det.SetString(bundle.RelationKeyIdentity, identity)
|
||||
det.SetString(bundle.RelationKeySpaceId, spaceId)
|
||||
det.SetString(bundle.RelationKeyLastModifiedBy, id)
|
||||
det.SetInt64(bundle.RelationKeyParticipantPermissions, int64(permissions))
|
||||
det.SetInt64(bundle.RelationKeyParticipantStatus, int64(status))
|
||||
det.SetBool(bundle.RelationKeyIsHiddenDiscovery, status != model.ParticipantStatus_Active)
|
||||
return det
|
||||
}
|
||||
|
|
|
@ -17,19 +17,18 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func TestParticipant_ModifyProfileDetails(t *testing.T) {
|
||||
// given
|
||||
fx := newParticipantFixture(t)
|
||||
defer fx.finish()
|
||||
details := pbtypes.ToStruct(map[string]interface{}{
|
||||
bundle.RelationKeyName.String(): "name",
|
||||
bundle.RelationKeyDescription.String(): "description",
|
||||
bundle.RelationKeyIconImage.String(): "icon",
|
||||
bundle.RelationKeyId.String(): "profile",
|
||||
bundle.RelationKeyGlobalName.String(): "global",
|
||||
details := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyName: domain.String("name"),
|
||||
bundle.RelationKeyDescription: domain.String("description"),
|
||||
bundle.RelationKeyIconImage: domain.String("icon"),
|
||||
bundle.RelationKeyId: domain.String("profile"),
|
||||
bundle.RelationKeyGlobalName: domain.String("global"),
|
||||
})
|
||||
|
||||
// when
|
||||
|
@ -37,14 +36,13 @@ func TestParticipant_ModifyProfileDetails(t *testing.T) {
|
|||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
details.Fields[bundle.RelationKeyIdentityProfileLink.String()] = pbtypes.String("profile")
|
||||
delete(details.Fields, bundle.RelationKeyId.String())
|
||||
fields := details.GetFields()
|
||||
participantFields := fx.CombinedDetails().GetFields()
|
||||
details.Set(bundle.RelationKeyIdentityProfileLink, domain.String("profile"))
|
||||
details.Delete(bundle.RelationKeyId)
|
||||
participantDetails := fx.CombinedDetails()
|
||||
participantRelationLinks := fx.GetRelationLinks()
|
||||
for key, _ := range details.Fields {
|
||||
require.Equal(t, fields[key], participantFields[key])
|
||||
require.True(t, participantRelationLinks.Has(key))
|
||||
for key, _ := range details.Iterate() {
|
||||
require.True(t, details.Get(key).Equal(participantDetails.Get(key)))
|
||||
require.True(t, participantRelationLinks.Has(key.String()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,21 +62,20 @@ func TestParticipant_ModifyParticipantAclState(t *testing.T) {
|
|||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
details := pbtypes.ToStruct(map[string]interface{}{
|
||||
bundle.RelationKeyId.String(): "id",
|
||||
bundle.RelationKeyIdentity.String(): "identity",
|
||||
bundle.RelationKeySpaceId.String(): "spaceId",
|
||||
bundle.RelationKeyLastModifiedBy.String(): "id",
|
||||
bundle.RelationKeyParticipantPermissions.String(): model.ParticipantPermissions_Owner,
|
||||
bundle.RelationKeyParticipantStatus.String(): model.ParticipantStatus_Active,
|
||||
bundle.RelationKeyIsHiddenDiscovery.String(): false,
|
||||
details := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyId: domain.String("id"),
|
||||
bundle.RelationKeyIdentity: domain.String("identity"),
|
||||
bundle.RelationKeySpaceId: domain.String("spaceId"),
|
||||
bundle.RelationKeyLastModifiedBy: domain.String("id"),
|
||||
bundle.RelationKeyParticipantPermissions: domain.Int64(model.ParticipantPermissions_Owner),
|
||||
bundle.RelationKeyParticipantStatus: domain.Int64(model.ParticipantStatus_Active),
|
||||
bundle.RelationKeyIsHiddenDiscovery: domain.Bool(false),
|
||||
})
|
||||
fields := details.GetFields()
|
||||
participantFields := fx.CombinedDetails().GetFields()
|
||||
participantDetails := fx.CombinedDetails()
|
||||
participantRelationLinks := fx.GetRelationLinks()
|
||||
for key, _ := range details.Fields {
|
||||
require.Equal(t, fields[key], participantFields[key])
|
||||
require.True(t, participantRelationLinks.Has(key))
|
||||
for key, _ := range details.Iterate() {
|
||||
require.True(t, details.Get(key).Equal(participantDetails.Get(key)))
|
||||
require.True(t, participantRelationLinks.Has(key.String()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,18 +95,17 @@ func TestParticipant_ModifyIdentityDetails(t *testing.T) {
|
|||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
details := pbtypes.ToStruct(map[string]interface{}{
|
||||
bundle.RelationKeyName.String(): "name",
|
||||
bundle.RelationKeyDescription.String(): "description",
|
||||
bundle.RelationKeyIconImage.String(): "icon",
|
||||
bundle.RelationKeyGlobalName.String(): "global",
|
||||
details := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyName: domain.String("name"),
|
||||
bundle.RelationKeyDescription: domain.String("description"),
|
||||
bundle.RelationKeyIconImage: domain.String("icon"),
|
||||
bundle.RelationKeyGlobalName: domain.String("global"),
|
||||
})
|
||||
fields := details.GetFields()
|
||||
participantFields := fx.CombinedDetails().GetFields()
|
||||
participantDetails := fx.CombinedDetails()
|
||||
participantRelationLinks := fx.GetRelationLinks()
|
||||
for key, _ := range details.Fields {
|
||||
require.Equal(t, fields[key], participantFields[key])
|
||||
require.True(t, participantRelationLinks.Has(key))
|
||||
for key, _ := range details.Iterate() {
|
||||
require.True(t, details.Get(key).Equal(participantDetails.Get(key)))
|
||||
require.True(t, participantRelationLinks.Has(key.String()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,9 +115,9 @@ func TestParticipant_Init(t *testing.T) {
|
|||
sb := smarttest.New("root")
|
||||
store := newStoreFixture(t)
|
||||
store.AddObjects(t, []objectstore.TestObject{{
|
||||
bundle.RelationKeySpaceId: pbtypes.String("spaceId"),
|
||||
bundle.RelationKeyId: pbtypes.String("root"),
|
||||
bundle.RelationKeyName: pbtypes.String("test"),
|
||||
bundle.RelationKeySpaceId: domain.String("spaceId"),
|
||||
bundle.RelationKeyId: domain.String("root"),
|
||||
bundle.RelationKeyName: domain.String("test"),
|
||||
}})
|
||||
|
||||
basicComponent := basic.NewBasic(sb, store, nil, nil, nil)
|
||||
|
@ -187,10 +183,10 @@ func newStoreFixture(t *testing.T) *spaceindex.StoreFixture {
|
|||
bundle.RelationKeySpaceId, bundle.RelationKeyParticipantStatus, bundle.RelationKeyIsHiddenDiscovery,
|
||||
} {
|
||||
store.AddObjects(t, []objectstore.TestObject{{
|
||||
bundle.RelationKeySpaceId: pbtypes.String("space1"),
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String(rel.URL()),
|
||||
bundle.RelationKeyId: pbtypes.String(rel.String()),
|
||||
bundle.RelationKeyRelationKey: pbtypes.String(rel.String()),
|
||||
bundle.RelationKeySpaceId: domain.String("space1"),
|
||||
bundle.RelationKeyUniqueKey: domain.String(rel.URL()),
|
||||
bundle.RelationKeyId: domain.String(rel.String()),
|
||||
bundle.RelationKeyRelationKey: domain.String(rel.String()),
|
||||
}})
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
type Profile struct {
|
||||
|
@ -82,7 +81,7 @@ func (p *Profile) CreationStateMigration(ctx *smartblock.InitContext) migration.
|
|||
Proc: func(st *state.State) {
|
||||
template.InitTemplate(st,
|
||||
template.WithObjectTypesAndLayout([]domain.TypeKey{bundle.TypeKeyProfile}, model.ObjectType_profile),
|
||||
template.WithDetail(bundle.RelationKeyLayoutAlign, pbtypes.Float64(float64(model.Block_AlignCenter))),
|
||||
template.WithDetail(bundle.RelationKeyLayoutAlign, domain.Int64(model.Block_AlignCenter)),
|
||||
migrationSetHidden,
|
||||
)
|
||||
},
|
||||
|
@ -90,7 +89,7 @@ func (p *Profile) CreationStateMigration(ctx *smartblock.InitContext) migration.
|
|||
}
|
||||
|
||||
func migrationSetHidden(st *state.State) {
|
||||
st.SetDetail(bundle.RelationKeyIsHidden.String(), pbtypes.Bool(true))
|
||||
st.SetDetail(bundle.RelationKeyIsHidden, domain.Bool(true))
|
||||
}
|
||||
|
||||
func migrationWithIdentityBlock(st *state.State) {
|
||||
|
@ -131,22 +130,16 @@ func (p *Profile) StateMigrations() migration.Migrations {
|
|||
})
|
||||
}
|
||||
|
||||
func (p *Profile) SetDetails(ctx session.Context, details []*model.Detail, showEvent bool) (err error) {
|
||||
func (p *Profile) SetDetails(ctx session.Context, details []domain.Detail, showEvent bool) (err error) {
|
||||
if err = p.AllOperations.SetDetails(ctx, details, showEvent); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
p.eventSender.Broadcast(&pb.Event{
|
||||
Messages: []*pb.EventMessage{
|
||||
{
|
||||
Value: &pb.EventMessageValueOfAccountDetails{
|
||||
AccountDetails: &pb.EventAccountDetails{
|
||||
ProfileId: p.Id(),
|
||||
Details: p.Details(),
|
||||
},
|
||||
},
|
||||
},
|
||||
p.eventSender.Broadcast(event.NewEventSingleMessage(p.SpaceID(), &pb.EventMessageValueOfAccountDetails{
|
||||
AccountDetails: &pb.EventAccountDetails{
|
||||
ProfileId: p.Id(),
|
||||
Details: p.Details().ToProto(),
|
||||
},
|
||||
})
|
||||
}))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
const InternalKeyOldProfileData = "oldprofile"
|
||||
|
@ -57,10 +56,10 @@ func ExtractCustomState(st *state.State) (userState *state.State, err error) {
|
|||
}
|
||||
newState := state.NewDocWithUniqueKey(st.RootId(), blocksMap, uk).(*state.State)
|
||||
newState.AddRelationLinks(st.GetRelationLinks()...)
|
||||
newStateDetails := pbtypes.CopyStruct(st.Details(), true)
|
||||
newName := pbtypes.GetString(newStateDetails, bundle.RelationKeyName.String()) + " [migrated]"
|
||||
newStateDetails.Fields[bundle.RelationKeyName.String()] = pbtypes.String(newName)
|
||||
newStateDetails.Fields[bundle.RelationKeyIsHidden.String()] = pbtypes.Bool(false)
|
||||
newStateDetails := st.Details().Copy()
|
||||
newName := newStateDetails.GetString(bundle.RelationKeyName) + " [migrated]"
|
||||
newStateDetails.SetString(bundle.RelationKeyName, newName)
|
||||
newStateDetails.SetBool(bundle.RelationKeyIsHidden, false)
|
||||
newState.SetDetails(newStateDetails)
|
||||
// remove the identity block
|
||||
newState.Unlink(identityBlockId)
|
||||
|
@ -73,7 +72,7 @@ func ExtractCustomState(st *state.State) (userState *state.State, err error) {
|
|||
return !slices.Contains(whitelistBlocks, s)
|
||||
})
|
||||
|
||||
whitelistDetailKeys := []string{
|
||||
whitelistDetailKeys := []domain.RelationKey{
|
||||
"iconEmoji",
|
||||
"name",
|
||||
"isHidden",
|
||||
|
@ -83,10 +82,10 @@ func ExtractCustomState(st *state.State) (userState *state.State, err error) {
|
|||
"iconImage",
|
||||
"iconOption",
|
||||
}
|
||||
var keysToRemove []string
|
||||
for k := range st.Details().GetFields() {
|
||||
if !slices.Contains(whitelistDetailKeys, k) {
|
||||
keysToRemove = append(keysToRemove, k)
|
||||
var keysToRemove []domain.RelationKey
|
||||
for key, _ := range st.Details().Iterate() {
|
||||
if !slices.Contains(whitelistDetailKeys, key) {
|
||||
keysToRemove = append(keysToRemove, key)
|
||||
}
|
||||
}
|
||||
// cleanup custom details from old state
|
||||
|
|
|
@ -7,9 +7,9 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -889,20 +889,20 @@ func TestProfileMigrationExtractCustomState(t *testing.T) {
|
|||
"iconImage",
|
||||
"iconOption",
|
||||
}
|
||||
for k, v := range originalStateCopy.Details().GetFields() {
|
||||
if k == bundle.RelationKeyName.String() {
|
||||
for k, v := range originalStateCopy.Details().Iterate() {
|
||||
if k == bundle.RelationKeyName {
|
||||
// should has suffix in the name
|
||||
v = pbtypes.String(v.GetStringValue() + " [migrated]")
|
||||
v = domain.String(v.String() + " [migrated]")
|
||||
}
|
||||
if k == bundle.RelationKeyIsHidden.String() {
|
||||
if k == bundle.RelationKeyIsHidden {
|
||||
// extracted state should not be hidden
|
||||
v = pbtypes.Bool(false)
|
||||
v = domain.Bool(false)
|
||||
}
|
||||
require.Truef(t, v.Equal(extractedState.Details().Fields[k]), "detail %s should be equal to original state", k)
|
||||
require.Truef(t, v.Equal(extractedState.Details().Get(k)), "detail %s should be equal to original state", k)
|
||||
}
|
||||
|
||||
for k, _ := range originalState.Details().GetFields() {
|
||||
require.Contains(t, whitelistedDetailKeys, k, "old state should not contain %s", k)
|
||||
for k, _ := range originalState.Details().Iterate() {
|
||||
require.Contains(t, whitelistedDetailKeys, k.String(), "old state should not contain %s", k)
|
||||
}
|
||||
require.Equal(t, bundle.TypeKeyPage, extractedState.ObjectTypeKey())
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
|
@ -26,21 +27,21 @@ func TestDependenciesSubscription(t *testing.T) {
|
|||
|
||||
fx.objectStore.AddObjects(t, testSpaceId, []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String(space1obj1),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(testSpaceId),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 1"),
|
||||
bundle.RelationKeyId: domain.String(space1obj1),
|
||||
bundle.RelationKeySpaceId: domain.String(testSpaceId),
|
||||
bundle.RelationKeyName: domain.String("Object 1"),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String(space1obj2),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(testSpaceId),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 2"),
|
||||
bundle.RelationKeyId: domain.String(space1obj2),
|
||||
bundle.RelationKeySpaceId: domain.String(testSpaceId),
|
||||
bundle.RelationKeyName: domain.String("Object 2"),
|
||||
},
|
||||
})
|
||||
fx.objectStore.AddObjects(t, "space2", []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String(space2obj1),
|
||||
bundle.RelationKeySpaceId: pbtypes.String("space2"),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 3"),
|
||||
bundle.RelationKeyId: domain.String(space2obj1),
|
||||
bundle.RelationKeySpaceId: domain.String("space2"),
|
||||
bundle.RelationKeyName: domain.String("Object 3"),
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -58,13 +59,11 @@ func TestDependenciesSubscription(t *testing.T) {
|
|||
)
|
||||
|
||||
fx.Doc = state.NewDoc(mainObjId, root.BuildMap()).NewState()
|
||||
objDetails := &types.Struct{
|
||||
Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyId.String(): pbtypes.String(mainObjId),
|
||||
bundle.RelationKeySpaceId.String(): pbtypes.String(testSpaceId),
|
||||
bundle.RelationKeyName.String(): pbtypes.String("Main object"),
|
||||
},
|
||||
}
|
||||
objDetails := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyId: domain.String(mainObjId),
|
||||
bundle.RelationKeySpaceId: domain.String(testSpaceId),
|
||||
bundle.RelationKeyName: domain.String("Main object"),
|
||||
})
|
||||
|
||||
fx.Doc.(*state.State).SetDetails(objDetails)
|
||||
|
||||
|
@ -142,21 +141,21 @@ func TestDependenciesSubscription(t *testing.T) {
|
|||
|
||||
fx.objectStore.AddObjects(t, testSpaceId, []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String(space1obj1),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(testSpaceId),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 1"),
|
||||
bundle.RelationKeyId: domain.String(space1obj1),
|
||||
bundle.RelationKeySpaceId: domain.String(testSpaceId),
|
||||
bundle.RelationKeyName: domain.String("Object 1"),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String(space1obj2),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(testSpaceId),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 2"),
|
||||
bundle.RelationKeyId: domain.String(space1obj2),
|
||||
bundle.RelationKeySpaceId: domain.String(testSpaceId),
|
||||
bundle.RelationKeyName: domain.String("Object 2"),
|
||||
},
|
||||
})
|
||||
fx.objectStore.AddObjects(t, "space2", []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String(space2obj1),
|
||||
bundle.RelationKeySpaceId: pbtypes.String("space2"),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 3"),
|
||||
bundle.RelationKeyId: domain.String(space2obj1),
|
||||
bundle.RelationKeySpaceId: domain.String("space2"),
|
||||
bundle.RelationKeyName: domain.String("Object 3"),
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/block/object/objectlink"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/internalflag"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
|
@ -18,7 +18,7 @@ func (sb *smartBlock) updateBackLinks(s *state.State) {
|
|||
log.With("objectID", sb.Id()).Errorf("failed to get inbound links from object store: %s", err)
|
||||
return
|
||||
}
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyBacklinks, pbtypes.StringList(backLinks))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyBacklinks, domain.StringList(backLinks))
|
||||
}
|
||||
|
||||
func (sb *smartBlock) injectLinksDetails(s *state.State) {
|
||||
|
@ -35,7 +35,7 @@ func (sb *smartBlock) injectLinksDetails(s *state.State) {
|
|||
RoundDateIdsToDay: true,
|
||||
})
|
||||
links = slice.RemoveMut(links, sb.Id())
|
||||
s.SetLocalDetail(bundle.RelationKeyLinks.String(), pbtypes.StringList(links))
|
||||
s.SetLocalDetail(bundle.RelationKeyLinks, domain.StringList(links))
|
||||
}
|
||||
|
||||
func (sb *smartBlock) injectMentions(s *state.State) {
|
||||
|
@ -51,7 +51,7 @@ func (sb *smartBlock) injectMentions(s *state.State) {
|
|||
NoImages: true,
|
||||
})
|
||||
mentions = slice.RemoveMut(mentions, sb.Id())
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyMentions, pbtypes.StringList(mentions))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyMentions, domain.StringList(mentions))
|
||||
}
|
||||
|
||||
func isBacklinksChanged(msgs []simple.EventMessage) bool {
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
// nolint:misspell
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
|
||||
"github.com/anyproto/any-sync/commonspace/objecttreebuilder"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/template"
|
||||
|
@ -120,7 +119,7 @@ func New(
|
|||
eventSender: eventSender,
|
||||
objectStore: objectStore,
|
||||
spaceIdResolver: spaceIdResolver,
|
||||
lastDepDetails: map[string]*pb.EventObjectDetailsSet{},
|
||||
lastDepDetails: map[string]*domain.Details{},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
@ -155,9 +154,9 @@ type SmartBlock interface {
|
|||
History() undo.History
|
||||
Relations(s *state.State) relationutils.Relations
|
||||
HasRelation(s *state.State, relationKey string) bool
|
||||
AddRelationLinks(ctx session.Context, relationIds ...string) (err error)
|
||||
AddRelationLinksToState(s *state.State, relationIds ...string) (err error)
|
||||
RemoveExtraRelations(ctx session.Context, relationKeys []string) (err error)
|
||||
AddRelationLinks(ctx session.Context, relationKeys ...domain.RelationKey) (err error)
|
||||
AddRelationLinksToState(s *state.State, relationKeys ...domain.RelationKey) (err error)
|
||||
RemoveExtraRelations(ctx session.Context, relationKeys []domain.RelationKey) (err error)
|
||||
SetVerticalAlign(ctx session.Context, align model.BlockVerticalAlign, ids ...string) error
|
||||
SetIsDeleted()
|
||||
IsDeleted() bool
|
||||
|
@ -190,7 +189,7 @@ type DocInfo struct {
|
|||
Heads []string
|
||||
Creator string
|
||||
Type domain.TypeKey
|
||||
Details *types.Struct
|
||||
Details *domain.Details
|
||||
|
||||
SmartblockType smartblock.SmartBlockType
|
||||
}
|
||||
|
@ -200,7 +199,7 @@ type InitContext struct {
|
|||
IsNewObject bool
|
||||
Source source.Source
|
||||
ObjectTypeKeys []domain.TypeKey
|
||||
RelationKeys []string
|
||||
RelationKeys []domain.RelationKey
|
||||
RequiredInternalRelationKeys []domain.RelationKey // bundled relations that MUST be present in the state
|
||||
State *state.State
|
||||
Relations []*model.Relation
|
||||
|
@ -235,7 +234,7 @@ type smartBlock struct {
|
|||
sessions map[string]session.Context
|
||||
undo undo.History
|
||||
source source.Source
|
||||
lastDepDetails map[string]*pb.EventObjectDetailsSet
|
||||
lastDepDetails map[string]*domain.Details
|
||||
restrictions restriction.Restrictions
|
||||
isDeleted bool
|
||||
disableLayouts bool
|
||||
|
@ -314,7 +313,7 @@ func (sb *smartBlock) Type() smartblock.SmartBlockType {
|
|||
}
|
||||
|
||||
func (sb *smartBlock) ObjectTypeID() string {
|
||||
return pbtypes.GetString(sb.Doc.Details(), bundle.RelationKeyType.String())
|
||||
return sb.Doc.Details().GetString(bundle.RelationKeyType)
|
||||
}
|
||||
|
||||
func (sb *smartBlock) Init(ctx *InitContext) (err error) {
|
||||
|
@ -357,9 +356,9 @@ func (sb *smartBlock) Init(ctx *InitContext) (err error) {
|
|||
}
|
||||
// Add bundled relations
|
||||
var relKeys []domain.RelationKey
|
||||
for k := range ctx.State.Details().GetFields() {
|
||||
for k, _ := range ctx.State.Details().Iterate() {
|
||||
if bundle.HasRelation(k) {
|
||||
relKeys = append(relKeys, domain.RelationKey(k))
|
||||
relKeys = append(relKeys, k)
|
||||
}
|
||||
}
|
||||
ctx.State.AddBundledRelationLinks(relKeys...)
|
||||
|
@ -379,14 +378,12 @@ func (sb *smartBlock) Init(ctx *InitContext) (err error) {
|
|||
func (sb *smartBlock) sendObjectCloseEvent(_ ApplyInfo) error {
|
||||
sb.sendEvent(&pb.Event{
|
||||
ContextId: sb.Id(),
|
||||
Messages: []*pb.EventMessage{{
|
||||
Value: &pb.EventMessageValueOfObjectClose{
|
||||
Messages: []*pb.EventMessage{
|
||||
event.NewMessage(sb.SpaceID(), &pb.EventMessageValueOfObjectClose{
|
||||
ObjectClose: &pb.EventObjectClose{
|
||||
Id: sb.Id(),
|
||||
},
|
||||
},
|
||||
}},
|
||||
})
|
||||
}}),
|
||||
}})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -397,7 +394,11 @@ func (sb *smartBlock) updateRestrictions() {
|
|||
return
|
||||
}
|
||||
sb.restrictions = r
|
||||
sb.SendEvent([]*pb.EventMessage{{Value: &pb.EventMessageValueOfObjectRestrictionsSet{ObjectRestrictionsSet: &pb.EventObjectRestrictionsSet{Id: sb.Id(), Restrictions: r.Proto()}}}})
|
||||
sb.SendEvent([]*pb.EventMessage{
|
||||
event.NewMessage(sb.SpaceID(), &pb.EventMessageValueOfObjectRestrictionsSet{
|
||||
ObjectRestrictionsSet: &pb.EventObjectRestrictionsSet{Id: sb.Id(), Restrictions: r.Proto()},
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
func (sb *smartBlock) SetIsDeleted() {
|
||||
|
@ -462,7 +463,7 @@ func (sb *smartBlock) fetchMeta() (details []*model.ObjectViewDetailsSet, err er
|
|||
|
||||
perSpace := sb.partitionIdsBySpace(sb.depIds)
|
||||
|
||||
recordsCh := make(chan *types.Struct, 10)
|
||||
recordsCh := make(chan *domain.Details, 10)
|
||||
sb.recordsSub = database.NewSubscription(nil, recordsCh)
|
||||
|
||||
var records []database.Record
|
||||
|
@ -496,13 +497,13 @@ func (sb *smartBlock) fetchMeta() (details []*model.ObjectViewDetailsSet, err er
|
|||
// add self details
|
||||
details = append(details, &model.ObjectViewDetailsSet{
|
||||
Id: sb.Id(),
|
||||
Details: sb.CombinedDetails(),
|
||||
Details: sb.CombinedDetails().ToProto(),
|
||||
})
|
||||
|
||||
for _, rec := range records {
|
||||
details = append(details, &model.ObjectViewDetailsSet{
|
||||
Id: pbtypes.GetString(rec.Details, bundle.RelationKeyId.String()),
|
||||
Details: rec.Details,
|
||||
Id: rec.Details.GetString(bundle.RelationKeyId),
|
||||
Details: rec.Details.ToProto(),
|
||||
})
|
||||
}
|
||||
go sb.metaListener(recordsCh)
|
||||
|
@ -545,7 +546,7 @@ func (sb *smartBlock) Unlock() {
|
|||
sb.Locker.Unlock()
|
||||
}
|
||||
|
||||
func (sb *smartBlock) metaListener(ch chan *types.Struct) {
|
||||
func (sb *smartBlock) metaListener(ch chan *domain.Details) {
|
||||
for {
|
||||
rec, ok := <-ch
|
||||
if !ok {
|
||||
|
@ -557,34 +558,29 @@ func (sb *smartBlock) metaListener(ch chan *types.Struct) {
|
|||
}
|
||||
}
|
||||
|
||||
func (sb *smartBlock) onMetaChange(details *types.Struct) {
|
||||
func (sb *smartBlock) onMetaChange(details *domain.Details) {
|
||||
if details == nil {
|
||||
return
|
||||
}
|
||||
id := pbtypes.GetString(details, bundle.RelationKeyId.String())
|
||||
msgs := []*pb.EventMessage{}
|
||||
id := details.GetString(bundle.RelationKeyId)
|
||||
var msgs []*pb.EventMessage
|
||||
if v, exists := sb.lastDepDetails[id]; exists {
|
||||
diff := pbtypes.StructDiff(v.Details, details)
|
||||
diff := domain.StructDiff(v, details)
|
||||
if id == sb.Id() {
|
||||
// if we've got update for ourselves, we are only interested in local-only details, because the rest details changes will be appended when applying records in the current sb
|
||||
diff = pbtypes.StructFilterKeys(diff, bundle.LocalRelationsKeys)
|
||||
diff = diff.CopyOnlyKeys(bundle.LocalRelationsKeys...)
|
||||
}
|
||||
|
||||
msgs = append(msgs, state.StructDiffIntoEvents(id, diff)...)
|
||||
msgs = append(msgs, state.StructDiffIntoEvents(sb.SpaceID(), id, diff)...)
|
||||
} else {
|
||||
msgs = append(msgs, &pb.EventMessage{
|
||||
Value: &pb.EventMessageValueOfObjectDetailsSet{
|
||||
ObjectDetailsSet: &pb.EventObjectDetailsSet{
|
||||
Id: id,
|
||||
Details: details,
|
||||
},
|
||||
msgs = append(msgs, event.NewMessage(sb.SpaceID(), &pb.EventMessageValueOfObjectDetailsSet{
|
||||
ObjectDetailsSet: &pb.EventObjectDetailsSet{
|
||||
Id: id,
|
||||
Details: details.ToProto(),
|
||||
},
|
||||
})
|
||||
}
|
||||
sb.lastDepDetails[id] = &pb.EventObjectDetailsSet{
|
||||
Id: id,
|
||||
Details: details,
|
||||
}))
|
||||
}
|
||||
sb.lastDepDetails[id] = details
|
||||
|
||||
if len(msgs) == 0 {
|
||||
return
|
||||
|
@ -687,14 +683,14 @@ func (sb *smartBlock) Apply(s *state.State, flags ...ApplyFlag) (err error) {
|
|||
if s.ParentState() != nil && s.ParentState().IsTheHeaderChange() {
|
||||
// for the first change allow to set the last modified date from the state
|
||||
// this used for the object imports
|
||||
lastModifiedFromState := pbtypes.GetInt64(s.LocalDetails(), bundle.RelationKeyLastModifiedDate.String())
|
||||
lastModifiedFromState := s.LocalDetails().GetInt64(bundle.RelationKeyLastModifiedDate)
|
||||
if lastModifiedFromState > 0 {
|
||||
lastModified = time.Unix(lastModifiedFromState, 0)
|
||||
}
|
||||
|
||||
if existingCreatedDate := pbtypes.GetInt64(s.LocalDetails(), bundle.RelationKeyCreatedDate.String()); existingCreatedDate == 0 || existingCreatedDate > lastModified.Unix() {
|
||||
if existingCreatedDate := s.LocalDetails().GetInt64(bundle.RelationKeyCreatedDate); existingCreatedDate == 0 || existingCreatedDate > lastModified.Unix() {
|
||||
// this can happen if we don't have creation date in the root change
|
||||
s.SetLocalDetail(bundle.RelationKeyCreatedDate.String(), pbtypes.Int64(lastModified.Unix()))
|
||||
s.SetLocalDetail(bundle.RelationKeyCreatedDate, domain.Int64(lastModified.Unix()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -709,7 +705,7 @@ func (sb *smartBlock) Apply(s *state.State, flags ...ApplyFlag) (err error) {
|
|||
migrationVersionUpdated = s.MigrationVersion() != parent.MigrationVersion()
|
||||
}
|
||||
|
||||
msgs, act, err := state.ApplyState(s, !sb.disableLayouts)
|
||||
msgs, act, err := state.ApplyState(sb.SpaceID(), s, !sb.disableLayouts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -739,15 +735,15 @@ func (sb *smartBlock) Apply(s *state.State, flags ...ApplyFlag) (err error) {
|
|||
}
|
||||
if !sb.source.ReadOnly() {
|
||||
// We can set details directly in object's state, they'll be indexed correctly
|
||||
st.SetLocalDetail(bundle.RelationKeyLastModifiedBy.String(), pbtypes.String(sb.currentParticipantId))
|
||||
st.SetLocalDetail(bundle.RelationKeyLastModifiedDate.String(), pbtypes.Int64(lastModified.Unix()))
|
||||
st.SetLocalDetail(bundle.RelationKeyLastModifiedBy, domain.String(sb.currentParticipantId))
|
||||
st.SetLocalDetail(bundle.RelationKeyLastModifiedDate, domain.Int64(lastModified.Unix()))
|
||||
}
|
||||
fileDetailsKeys := st.FileRelationKeys()
|
||||
var fileDetailsKeysFiltered []string
|
||||
var fileDetailsKeysFiltered []domain.RelationKey
|
||||
for _, ch := range changes {
|
||||
if ds := ch.GetDetailsSet(); ds != nil {
|
||||
if slice.FindPos(fileDetailsKeys, ds.Key) != -1 {
|
||||
fileDetailsKeysFiltered = append(fileDetailsKeysFiltered, ds.Key)
|
||||
if slice.FindPos(fileDetailsKeys, domain.RelationKey(ds.Key)) != -1 {
|
||||
fileDetailsKeysFiltered = append(fileDetailsKeysFiltered, domain.RelationKey(ds.Key))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -908,7 +904,7 @@ func (sb *smartBlock) History() undo.History {
|
|||
return sb.undo
|
||||
}
|
||||
|
||||
func (sb *smartBlock) AddRelationLinks(ctx session.Context, relationKeys ...string) (err error) {
|
||||
func (sb *smartBlock) AddRelationLinks(ctx session.Context, relationKeys ...domain.RelationKey) (err error) {
|
||||
s := sb.NewStateCtx(ctx)
|
||||
if err = sb.AddRelationLinksToState(s, relationKeys...); err != nil {
|
||||
return
|
||||
|
@ -916,7 +912,7 @@ func (sb *smartBlock) AddRelationLinks(ctx session.Context, relationKeys ...stri
|
|||
return sb.Apply(s)
|
||||
}
|
||||
|
||||
func (sb *smartBlock) AddRelationLinksToState(s *state.State, relationKeys ...string) (err error) {
|
||||
func (sb *smartBlock) AddRelationLinksToState(s *state.State, relationKeys ...domain.RelationKey) (err error) {
|
||||
if len(relationKeys) == 0 {
|
||||
return
|
||||
}
|
||||
|
@ -946,7 +942,7 @@ func (sb *smartBlock) injectLocalDetails(s *state.State) error {
|
|||
// so we don't need to traverse changes every time
|
||||
keys := bundle.LocalAndDerivedRelationKeys
|
||||
|
||||
localDetailsFromStore := pbtypes.StructFilterKeys(details, keys)
|
||||
localDetailsFromStore := details.CopyOnlyKeys(keys...)
|
||||
|
||||
s.InjectLocalDetails(localDetailsFromStore)
|
||||
if p := s.ParentState(); p != nil && !hasPendingLocalDetails {
|
||||
|
@ -961,21 +957,21 @@ func (sb *smartBlock) injectLocalDetails(s *state.State) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (sb *smartBlock) getDetailsFromStore() (*types.Struct, error) {
|
||||
func (sb *smartBlock) getDetailsFromStore() (*domain.Details, error) {
|
||||
storedDetails, err := sb.spaceIndex.GetDetails(sb.Id())
|
||||
if err != nil || storedDetails == nil {
|
||||
return nil, err
|
||||
}
|
||||
return pbtypes.CopyStruct(storedDetails.GetDetails(), true), nil
|
||||
return storedDetails.Copy(), nil
|
||||
}
|
||||
|
||||
func (sb *smartBlock) appendPendingDetails(details *types.Struct) (resultDetails *types.Struct, hasPendingLocalDetails bool) {
|
||||
func (sb *smartBlock) appendPendingDetails(details *domain.Details) (resultDetails *domain.Details, hasPendingLocalDetails bool) {
|
||||
// Consume pending details
|
||||
err := sb.spaceIndex.UpdatePendingLocalDetails(sb.Id(), func(pending *types.Struct) (*types.Struct, error) {
|
||||
if len(pending.GetFields()) > 0 {
|
||||
err := sb.spaceIndex.UpdatePendingLocalDetails(sb.Id(), func(pending *domain.Details) (*domain.Details, error) {
|
||||
if pending.Len() > 0 {
|
||||
hasPendingLocalDetails = true
|
||||
}
|
||||
details = pbtypes.StructMerge(details, pending, false)
|
||||
details = details.Merge(pending)
|
||||
return nil, nil
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -1003,14 +999,14 @@ func (sb *smartBlock) injectCreationInfo(s *state.State) error {
|
|||
}
|
||||
|
||||
if creatorIdentityObjectId != "" {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyProfileOwnerIdentity, pbtypes.String(creatorIdentityObjectId))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyProfileOwnerIdentity, domain.String(creatorIdentityObjectId))
|
||||
}
|
||||
} else {
|
||||
// make sure we don't have this relation for other objects
|
||||
s.RemoveLocalDetail(bundle.RelationKeyProfileOwnerIdentity.String())
|
||||
s.RemoveLocalDetail(bundle.RelationKeyProfileOwnerIdentity)
|
||||
}
|
||||
|
||||
if pbtypes.GetString(s.LocalDetails(), bundle.RelationKeyCreator.String()) != "" && pbtypes.GetInt64(s.LocalDetails(), bundle.RelationKeyCreatedDate.String()) != 0 {
|
||||
if s.LocalDetails().GetString(bundle.RelationKeyCreator) != "" && s.LocalDetails().GetInt64(bundle.RelationKeyCreatedDate) != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1020,24 +1016,24 @@ func (sb *smartBlock) injectCreationInfo(s *state.State) error {
|
|||
}
|
||||
|
||||
if creatorIdentityObjectId != "" {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyCreator, pbtypes.String(creatorIdentityObjectId))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyCreator, domain.String(creatorIdentityObjectId))
|
||||
} else {
|
||||
// For derived objects we set current identity
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyCreator, pbtypes.String(sb.currentParticipantId))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyCreator, domain.String(sb.currentParticipantId))
|
||||
}
|
||||
|
||||
if originalCreated := s.OriginalCreatedTimestamp(); originalCreated > 0 {
|
||||
// means we have imported object, so we need to set original created date
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyCreatedDate, pbtypes.Float64(float64(originalCreated)))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyCreatedDate, domain.Int64(originalCreated))
|
||||
// Only set AddedDate once because we have a side effect with treeCreatedDate:
|
||||
// - When we import object, treeCreateDate is set to time.Now()
|
||||
// - But after push it is changed to original modified date
|
||||
// - So after account recovery we will get treeCreateDate = original modified date, which is not equal to AddedDate
|
||||
if pbtypes.GetInt64(s.Details(), bundle.RelationKeyAddedDate.String()) == 0 {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyAddedDate, pbtypes.Float64(float64(treeCreatedDate)))
|
||||
if s.Details().GetInt64(bundle.RelationKeyAddedDate) == 0 {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyAddedDate, domain.Int64(treeCreatedDate))
|
||||
}
|
||||
} else {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyCreatedDate, pbtypes.Float64(float64(treeCreatedDate)))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyCreatedDate, domain.Int64(treeCreatedDate))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -1053,7 +1049,7 @@ func (sb *smartBlock) SetVerticalAlign(ctx session.Context, align model.BlockVer
|
|||
return sb.Apply(s)
|
||||
}
|
||||
|
||||
func (sb *smartBlock) RemoveExtraRelations(ctx session.Context, relationIds []string) (err error) {
|
||||
func (sb *smartBlock) RemoveExtraRelations(ctx session.Context, relationIds []domain.RelationKey) (err error) {
|
||||
st := sb.NewStateCtx(ctx)
|
||||
st.RemoveRelation(relationIds...)
|
||||
|
||||
|
@ -1071,7 +1067,7 @@ func (sb *smartBlock) StateAppend(f func(d state.Doc) (s *state.State, changes [
|
|||
sb.updateRestrictions()
|
||||
sb.injectDerivedDetails(s, sb.SpaceID(), sb.Type())
|
||||
sb.execHooks(HookBeforeApply, ApplyInfo{State: s})
|
||||
msgs, act, err := state.ApplyState(s, !sb.disableLayouts)
|
||||
msgs, act, err := state.ApplyState(sb.SpaceID(), s, !sb.disableLayouts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1106,7 +1102,7 @@ func (sb *smartBlock) StateRebuild(d state.Doc) (err error) {
|
|||
d.(*state.State).SetParent(sb.Doc.(*state.State))
|
||||
// todo: make store diff
|
||||
sb.execHooks(HookBeforeApply, ApplyInfo{State: d.(*state.State)})
|
||||
msgs, _, err := state.ApplyState(d.(*state.State), !sb.disableLayouts)
|
||||
msgs, _, err := state.ApplyState(sb.SpaceID(), d.(*state.State), !sb.disableLayouts)
|
||||
log.Infof("changes: stateRebuild: %d events", len(msgs))
|
||||
if err != nil {
|
||||
// can't make diff - reopen doc
|
||||
|
@ -1181,17 +1177,18 @@ func hasDepIds(relations pbtypes.RelationLinks, act *undo.Action) bool {
|
|||
if act.Details.Before == nil || act.Details.After == nil {
|
||||
return true
|
||||
}
|
||||
for k, after := range act.Details.After.Fields {
|
||||
rel := relations.Get(k)
|
||||
|
||||
for k, after := range act.Details.After.Iterate() {
|
||||
rel := relations.Get(string(k))
|
||||
if rel != nil && (rel.Format == model.RelationFormat_status ||
|
||||
rel.Format == model.RelationFormat_tag ||
|
||||
rel.Format == model.RelationFormat_object ||
|
||||
rel.Format == model.RelationFormat_file ||
|
||||
isCoverId(rel)) {
|
||||
|
||||
before := act.Details.Before.Fields[k]
|
||||
before := act.Details.Before.Get(k)
|
||||
// Check that value is actually changed
|
||||
if before == nil || !before.Equal(after) {
|
||||
if !before.Ok() || !before.Equal(after) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -1226,7 +1223,7 @@ func isCoverId(rel *model.RelationLink) bool {
|
|||
return rel.Key == bundle.RelationKeyCoverId.String()
|
||||
}
|
||||
|
||||
func getChangedFileHashes(s *state.State, fileDetailKeys []string, act undo.Action) (hashes []string) {
|
||||
func getChangedFileHashes(s *state.State, fileDetailKeys []domain.RelationKey, act undo.Action) (hashes []string) {
|
||||
for _, nb := range act.Add {
|
||||
if fh, ok := nb.(simple.FileHashes); ok {
|
||||
hashes = fh.FillFileHashes(hashes)
|
||||
|
@ -1239,11 +1236,11 @@ func getChangedFileHashes(s *state.State, fileDetailKeys []string, act undo.Acti
|
|||
}
|
||||
if act.Details != nil {
|
||||
det := act.Details.After
|
||||
if det != nil && det.Fields != nil {
|
||||
for _, field := range fileDetailKeys {
|
||||
if list := pbtypes.GetStringList(det, field); list != nil {
|
||||
if det != nil {
|
||||
for _, detKey := range fileDetailKeys {
|
||||
if list := det.GetStringList(detKey); len(list) > 0 {
|
||||
hashes = append(hashes, list...)
|
||||
} else if s := pbtypes.GetString(det, field); s != "" {
|
||||
} else if s := det.GetString(detKey); s != "" {
|
||||
hashes = append(hashes, s)
|
||||
}
|
||||
}
|
||||
|
@ -1318,10 +1315,10 @@ func (sb *smartBlock) GetDocInfo() DocInfo {
|
|||
}
|
||||
|
||||
func (sb *smartBlock) getDocInfo(st *state.State) DocInfo {
|
||||
creator := pbtypes.GetString(st.Details(), bundle.RelationKeyCreator.String())
|
||||
creator := st.Details().GetString(bundle.RelationKeyCreator)
|
||||
|
||||
// we don't want any hidden or internal relations here. We want to capture the meaningful outgoing links only
|
||||
links := pbtypes.GetStringList(sb.LocalDetails(), bundle.RelationKeyLinks.String())
|
||||
links := sb.LocalDetails().GetStringList(bundle.RelationKeyLinks)
|
||||
// so links will have this order
|
||||
// 1. Simple blocks: links, mentions in the text
|
||||
// 2. Relations(format==Object)
|
||||
|
@ -1337,7 +1334,7 @@ func (sb *smartBlock) getDocInfo(st *state.State) DocInfo {
|
|||
// todo: heads in source and the state may be inconsistent?
|
||||
heads := sb.source.Heads()
|
||||
if len(heads) == 0 {
|
||||
lastChangeId := pbtypes.GetString(st.LocalDetails(), bundle.RelationKeyLastChangeId.String())
|
||||
lastChangeId := st.LocalDetails().GetString(bundle.RelationKeyLastChangeId)
|
||||
if lastChangeId != "" {
|
||||
heads = []string{lastChangeId}
|
||||
}
|
||||
|
@ -1376,17 +1373,17 @@ func removeInternalFlags(s *state.State) {
|
|||
}
|
||||
|
||||
func (sb *smartBlock) setRestrictionsDetail(s *state.State) {
|
||||
rawRestrictions := make([]int, len(sb.Restrictions().Object))
|
||||
rawRestrictions := make([]float64, len(sb.Restrictions().Object))
|
||||
for i, r := range sb.Restrictions().Object {
|
||||
rawRestrictions[i] = int(r)
|
||||
rawRestrictions[i] = float64(r)
|
||||
}
|
||||
s.SetLocalDetail(bundle.RelationKeyRestrictions.String(), pbtypes.IntList(rawRestrictions...))
|
||||
s.SetLocalDetail(bundle.RelationKeyRestrictions, domain.Float64List(rawRestrictions))
|
||||
|
||||
// todo: verify this logic with clients
|
||||
if sb.Restrictions().Object.Check(model.Restrictions_Details) != nil &&
|
||||
sb.Restrictions().Object.Check(model.Restrictions_Blocks) != nil {
|
||||
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyIsReadonly, pbtypes.Bool(true))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyIsReadonly, domain.Bool(true))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1454,15 +1451,16 @@ func SkipFullTextIfHeadsNotChanged(o *IndexOptions) {
|
|||
|
||||
// injectDerivedDetails injects the local data
|
||||
func (sb *smartBlock) injectDerivedDetails(s *state.State, spaceID string, sbt smartblock.SmartBlockType) {
|
||||
// TODO Pick from source
|
||||
id := s.RootId()
|
||||
if id != "" {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyId, pbtypes.String(id))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyId, domain.String(id))
|
||||
}
|
||||
|
||||
if v, ok := s.Details().GetFields()[bundle.RelationKeyFileBackupStatus.String()]; ok {
|
||||
status := filesyncstatus.Status(v.GetNumberValue())
|
||||
if v, ok := s.Details().TryInt64(bundle.RelationKeyFileBackupStatus); ok {
|
||||
status := filesyncstatus.Status(v)
|
||||
// Clients expect syncstatus constants in this relation
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyFileSyncStatus, pbtypes.Int64(int64(status.ToSyncStatus())))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyFileSyncStatus, domain.Int64(status.ToSyncStatus()))
|
||||
}
|
||||
|
||||
if info := s.GetFileInfo(); info.FileId != "" {
|
||||
|
@ -1476,9 +1474,9 @@ func (sb *smartBlock) injectDerivedDetails(s *state.State, spaceID string, sbt s
|
|||
}
|
||||
|
||||
if spaceID != "" {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeySpaceId, pbtypes.String(spaceID))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeySpaceId, domain.String(spaceID))
|
||||
} else {
|
||||
log.Errorf("InjectDerivedDetails: failed to set space id for %s: no space id provided, but in details: %s", id, pbtypes.GetString(s.LocalDetails(), bundle.RelationKeySpaceId.String()))
|
||||
log.Errorf("InjectDerivedDetails: failed to set space id for %s: no space id provided, but in details: %s", id, s.LocalDetails().GetString(bundle.RelationKeySpaceId))
|
||||
}
|
||||
if ot := s.ObjectTypeKey(); ot != "" {
|
||||
typeID, err := sb.space.GetTypeIdByKey(context.Background(), ot)
|
||||
|
@ -1486,7 +1484,7 @@ func (sb *smartBlock) injectDerivedDetails(s *state.State, spaceID string, sbt s
|
|||
log.Errorf("failed to get type id for %s: %v", ot, err)
|
||||
}
|
||||
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyType, pbtypes.String(typeID))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyType, domain.String(typeID))
|
||||
}
|
||||
|
||||
if uki := s.UniqueKeyInternal(); uki != "" {
|
||||
|
@ -1501,7 +1499,7 @@ func (sb *smartBlock) injectDerivedDetails(s *state.State, spaceID string, sbt s
|
|||
if err != nil {
|
||||
log.Errorf("failed to get unique key for %s: %v", uki, err)
|
||||
} else {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyUniqueKey, pbtypes.String(uk.Marshal()))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyUniqueKey, domain.String(uk.Marshal()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1514,16 +1512,16 @@ func (sb *smartBlock) injectDerivedDetails(s *state.State, spaceID string, sbt s
|
|||
|
||||
snippet := s.Snippet()
|
||||
if snippet != "" || s.LocalDetails() != nil {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeySnippet, pbtypes.String(snippet))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeySnippet, domain.String(snippet))
|
||||
}
|
||||
|
||||
// Set isDeleted relation only if isUninstalled is present in details
|
||||
if isUninstalled := s.Details().GetFields()[bundle.RelationKeyIsUninstalled.String()]; isUninstalled != nil {
|
||||
if isUninstalled, ok := s.Details().TryBool(bundle.RelationKeyIsUninstalled); ok {
|
||||
var isDeleted bool
|
||||
if isUninstalled.GetBoolValue() {
|
||||
if isUninstalled {
|
||||
isDeleted = true
|
||||
}
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyIsDeleted, pbtypes.Bool(isDeleted))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyIsDeleted, domain.Bool(isDeleted))
|
||||
}
|
||||
|
||||
sb.injectLinksDetails(s)
|
||||
|
@ -1532,7 +1530,7 @@ func (sb *smartBlock) injectDerivedDetails(s *state.State, spaceID string, sbt s
|
|||
}
|
||||
|
||||
func (sb *smartBlock) deriveChatId(s *state.State) error {
|
||||
hasChat := pbtypes.GetBool(s.Details(), bundle.RelationKeyHasChat.String())
|
||||
hasChat := s.Details().GetBool(bundle.RelationKeyHasChat)
|
||||
if hasChat {
|
||||
chatUk, err := domain.NewUniqueKey(smartblock.SmartBlockTypeChatDerivedObject, sb.Id())
|
||||
if err != nil {
|
||||
|
@ -1543,7 +1541,7 @@ func (sb *smartBlock) deriveChatId(s *state.State) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyChatId, pbtypes.String(chatId))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyChatId, domain.String(chatId))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -30,7 +29,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/internalflag"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func TestSmartBlock_Init(t *testing.T) {
|
||||
|
@ -120,7 +118,7 @@ func TestBasic_SetAlign(t *testing.T) {
|
|||
// then
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, model.Block_AlignRight, st.Get("title").Model().Align)
|
||||
assert.Equal(t, int64(model.Block_AlignRight), pbtypes.GetInt64(st.Details(), bundle.RelationKeyLayoutAlign.String()))
|
||||
assert.Equal(t, int64(model.Block_AlignRight), st.Details().GetInt64(bundle.RelationKeyLayoutAlign))
|
||||
})
|
||||
|
||||
}
|
||||
|
@ -131,21 +129,13 @@ func TestSmartBlock_getDetailsFromStore(t *testing.T) {
|
|||
// given
|
||||
fx := newFixture(id, t)
|
||||
|
||||
details := &types.Struct{
|
||||
Fields: map[string]*types.Value{
|
||||
"id": pbtypes.String(id),
|
||||
"number": pbtypes.Float64(2.18281828459045),
|
||||
"🔥": pbtypes.StringList([]string{"Jeanne d'Arc", "Giordano Bruno", "Capocchio"}),
|
||||
},
|
||||
}
|
||||
|
||||
err := fx.store.UpdateObjectDetails(context.Background(), id, &types.Struct{
|
||||
Fields: map[string]*types.Value{
|
||||
"id": pbtypes.String(id),
|
||||
"number": pbtypes.Float64(2.18281828459045),
|
||||
"🔥": pbtypes.StringList([]string{"Jeanne d'Arc", "Giordano Bruno", "Capocchio"}),
|
||||
},
|
||||
details := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
"id": domain.String(id),
|
||||
"number": domain.Float64(2.18281828459045),
|
||||
"🔥": domain.StringList([]string{"Jeanne d'Arc", "Giordano Bruno", "Capocchio"}),
|
||||
})
|
||||
|
||||
err := fx.store.UpdateObjectDetails(context.Background(), id, details)
|
||||
require.NoError(t, err)
|
||||
|
||||
// when
|
||||
|
@ -185,13 +175,13 @@ func TestSmartBlock_injectBackLinks(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
st := state.NewDoc("", nil).NewState()
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyBacklinks, pbtypes.StringList(backLinks))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyBacklinks, domain.StringList(backLinks))
|
||||
|
||||
// when
|
||||
fx.updateBackLinks(st)
|
||||
|
||||
// then
|
||||
assert.Equal(t, newBackLinks, pbtypes.GetStringList(st.CombinedDetails(), bundle.RelationKeyBacklinks.String()))
|
||||
assert.Equal(t, newBackLinks, st.CombinedDetails().GetStringList(bundle.RelationKeyBacklinks))
|
||||
})
|
||||
|
||||
t.Run("back links were found in object store", func(t *testing.T) {
|
||||
|
@ -214,8 +204,8 @@ func TestSmartBlock_injectBackLinks(t *testing.T) {
|
|||
|
||||
// then
|
||||
details := st.CombinedDetails()
|
||||
assert.NotNil(t, pbtypes.GetStringList(details, bundle.RelationKeyBacklinks.String()))
|
||||
assert.Equal(t, backLinks, pbtypes.GetStringList(details, bundle.RelationKeyBacklinks.String()))
|
||||
assert.NotNil(t, details.GetStringList(bundle.RelationKeyBacklinks))
|
||||
assert.Equal(t, backLinks, details.GetStringList(bundle.RelationKeyBacklinks))
|
||||
})
|
||||
|
||||
t.Run("back links were not found in object store", func(t *testing.T) {
|
||||
|
@ -228,7 +218,7 @@ func TestSmartBlock_injectBackLinks(t *testing.T) {
|
|||
fx.updateBackLinks(st)
|
||||
|
||||
// then
|
||||
assert.Len(t, pbtypes.GetStringList(st.CombinedDetails(), bundle.RelationKeyBacklinks.String()), 0)
|
||||
assert.Len(t, st.CombinedDetails().GetStringList(bundle.RelationKeyBacklinks), 0)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -240,24 +230,24 @@ func TestSmartBlock_updatePendingDetails(t *testing.T) {
|
|||
fx := newFixture(id, t)
|
||||
|
||||
var hasPendingDetails bool
|
||||
details := &types.Struct{Fields: map[string]*types.Value{}}
|
||||
details := domain.NewDetails()
|
||||
|
||||
// when
|
||||
_, result := fx.appendPendingDetails(details)
|
||||
|
||||
// then
|
||||
assert.Equal(t, hasPendingDetails, result)
|
||||
assert.Zero(t, len(details.Fields))
|
||||
assert.Zero(t, details.Len())
|
||||
})
|
||||
|
||||
t.Run("found pending details", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(id, t)
|
||||
|
||||
details := &types.Struct{Fields: map[string]*types.Value{}}
|
||||
details := domain.NewDetails()
|
||||
|
||||
err := fx.store.UpdatePendingLocalDetails(id, func(det *types.Struct) (*types.Struct, error) {
|
||||
det.Fields[bundle.RelationKeyIsDeleted.String()] = pbtypes.Bool(false)
|
||||
err := fx.store.UpdatePendingLocalDetails(id, func(det *domain.Details) (*domain.Details, error) {
|
||||
det.Set(bundle.RelationKeyIsDeleted, domain.Bool(false))
|
||||
return det, nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
@ -266,12 +256,10 @@ func TestSmartBlock_updatePendingDetails(t *testing.T) {
|
|||
got, _ := fx.appendPendingDetails(details)
|
||||
|
||||
// then
|
||||
want := &types.Struct{
|
||||
Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyId.String(): pbtypes.String(id),
|
||||
bundle.RelationKeyIsDeleted.String(): pbtypes.Bool(false),
|
||||
},
|
||||
}
|
||||
want := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyId: domain.String(id),
|
||||
bundle.RelationKeyIsDeleted: domain.Bool(false),
|
||||
})
|
||||
assert.Equal(t, want, got)
|
||||
})
|
||||
|
||||
|
@ -279,7 +267,7 @@ func TestSmartBlock_updatePendingDetails(t *testing.T) {
|
|||
// given
|
||||
fx := newFixture(id, t)
|
||||
|
||||
details := &types.Struct{}
|
||||
details := domain.NewDetails()
|
||||
|
||||
// when
|
||||
_, hasPendingDetails := fx.appendPendingDetails(details)
|
||||
|
@ -302,18 +290,18 @@ func TestSmartBlock_injectCreationInfo(t *testing.T) {
|
|||
}
|
||||
sb := &smartBlock{source: src}
|
||||
s := &state.State{}
|
||||
s.SetLocalDetails(&types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyCreator.String(): pbtypes.String(creator),
|
||||
bundle.RelationKeyCreatedDate.String(): pbtypes.Int64(creationDate),
|
||||
}})
|
||||
s.SetLocalDetails(domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyCreator: domain.String(creator),
|
||||
bundle.RelationKeyCreatedDate: domain.Int64(creationDate),
|
||||
}))
|
||||
|
||||
// when
|
||||
err := sb.injectCreationInfo(s)
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, creator, pbtypes.GetString(s.LocalDetails(), bundle.RelationKeyCreator.String()))
|
||||
assert.Equal(t, creationDate, pbtypes.GetInt64(s.LocalDetails(), bundle.RelationKeyCreatedDate.String()))
|
||||
assert.Equal(t, creator, s.LocalDetails().GetString(bundle.RelationKeyCreator))
|
||||
assert.Equal(t, creationDate, s.LocalDetails().GetInt64(bundle.RelationKeyCreatedDate))
|
||||
})
|
||||
|
||||
t.Run("both creator and creation date are found", func(t *testing.T) {
|
||||
|
@ -331,9 +319,9 @@ func TestSmartBlock_injectCreationInfo(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, creator, pbtypes.GetString(s.LocalDetails(), bundle.RelationKeyCreator.String()))
|
||||
assert.Equal(t, creator, s.LocalDetails().GetString(bundle.RelationKeyCreator))
|
||||
assert.NotNil(t, s.GetRelationLinks().Get(bundle.RelationKeyCreator.String()))
|
||||
assert.Equal(t, creationDate, pbtypes.GetInt64(s.LocalDetails(), bundle.RelationKeyCreatedDate.String()))
|
||||
assert.Equal(t, creationDate, s.LocalDetails().GetInt64(bundle.RelationKeyCreatedDate))
|
||||
assert.NotNil(t, s.GetRelationLinks().Get(bundle.RelationKeyCreatedDate.String()))
|
||||
})
|
||||
|
||||
|
@ -357,13 +345,13 @@ func Test_removeInternalFlags(t *testing.T) {
|
|||
t.Run("no flags - no changes", func(t *testing.T) {
|
||||
// given
|
||||
st := state.NewDoc("test", nil).(*state.State)
|
||||
st.SetDetail(bundle.RelationKeyInternalFlags.String(), pbtypes.IntList())
|
||||
st.SetDetail(bundle.RelationKeyInternalFlags, domain.Int64List([]int64{}))
|
||||
|
||||
// when
|
||||
removeInternalFlags(st)
|
||||
|
||||
// then
|
||||
assert.Empty(t, pbtypes.GetIntList(st.CombinedDetails(), bundle.RelationKeyInternalFlags.String()))
|
||||
assert.Empty(t, st.CombinedDetails().GetInt64List(bundle.RelationKeyInternalFlags))
|
||||
})
|
||||
t.Run("EmptyDelete flag is not removed when state is empty", func(t *testing.T) {
|
||||
// given
|
||||
|
@ -375,14 +363,14 @@ func Test_removeInternalFlags(t *testing.T) {
|
|||
removeInternalFlags(st)
|
||||
|
||||
// then
|
||||
assert.Len(t, pbtypes.GetIntList(st.CombinedDetails(), bundle.RelationKeyInternalFlags.String()), 1)
|
||||
assert.Len(t, st.CombinedDetails().GetInt64List(bundle.RelationKeyInternalFlags), 1)
|
||||
})
|
||||
t.Run("all flags are removed when title is not empty", func(t *testing.T) {
|
||||
// given
|
||||
st := state.NewDoc("test", map[string]simple.Block{
|
||||
"title": simple.New(&model.Block{Id: "title"}),
|
||||
}).(*state.State)
|
||||
st.SetDetail(bundle.RelationKeyName.String(), pbtypes.String("some name"))
|
||||
st.SetDetail(bundle.RelationKeyName, domain.String("some name"))
|
||||
flags := defaultInternalFlags()
|
||||
flags.AddToState(st)
|
||||
|
||||
|
@ -390,7 +378,7 @@ func Test_removeInternalFlags(t *testing.T) {
|
|||
removeInternalFlags(st)
|
||||
|
||||
// then
|
||||
assert.Empty(t, pbtypes.GetIntList(st.CombinedDetails(), bundle.RelationKeyInternalFlags.String()))
|
||||
assert.Empty(t, st.CombinedDetails().GetInt64List(bundle.RelationKeyInternalFlags))
|
||||
})
|
||||
t.Run("all flags are removed when state has non-empty text blocks", func(t *testing.T) {
|
||||
// given
|
||||
|
@ -407,7 +395,7 @@ func Test_removeInternalFlags(t *testing.T) {
|
|||
removeInternalFlags(st)
|
||||
|
||||
// then
|
||||
assert.Empty(t, pbtypes.GetIntList(st.CombinedDetails(), bundle.RelationKeyInternalFlags.String()))
|
||||
assert.Empty(t, st.CombinedDetails().GetInt64List(bundle.RelationKeyInternalFlags))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -425,8 +413,8 @@ func TestInjectLocalDetails(t *testing.T) {
|
|||
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, fx.source.creator, pbtypes.GetString(st.LocalDetails(), bundle.RelationKeyCreator.String()))
|
||||
assert.Equal(t, fx.source.createdDate, pbtypes.GetInt64(st.LocalDetails(), bundle.RelationKeyCreatedDate.String()))
|
||||
assert.Equal(t, fx.source.creator, st.LocalDetails().GetString(bundle.RelationKeyCreator))
|
||||
assert.Equal(t, fx.source.createdDate, st.LocalDetails().GetInt64(bundle.RelationKeyCreatedDate))
|
||||
})
|
||||
|
||||
// TODO More tests
|
||||
|
@ -447,13 +435,13 @@ func TestInjectDerivedDetails(t *testing.T) {
|
|||
"link": simple.New(&model.Block{Id: "link", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "some_obj"}}}),
|
||||
}).NewState()
|
||||
st.AddRelationLinks(&model.RelationLink{Key: bundle.RelationKeyAssignee.String(), Format: model.RelationFormat_object})
|
||||
st.SetDetail(bundle.RelationKeyAssignee.String(), pbtypes.String("Kirill"))
|
||||
st.SetDetail(bundle.RelationKeyAssignee, domain.StringList([]string{"Kirill"}))
|
||||
|
||||
// when
|
||||
fx.injectDerivedDetails(st, spaceId, smartblock.SmartBlockTypePage)
|
||||
|
||||
// then
|
||||
assert.Len(t, pbtypes.GetStringList(st.LocalDetails(), bundle.RelationKeyLinks.String()), 3)
|
||||
assert.Len(t, st.LocalDetails().GetStringList(bundle.RelationKeyLinks), 3)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
|
||||
"github.com/anyproto/any-sync/commonspace/objecttreebuilder"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
|
@ -25,7 +24,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/threads"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func New(id string) *SmartTest {
|
||||
|
@ -217,17 +215,17 @@ func (st *SmartTest) TemplateCreateFromObjectState() (*state.State, error) {
|
|||
return st.Doc.NewState().Copy(), nil
|
||||
}
|
||||
|
||||
func (st *SmartTest) AddRelationLinks(ctx session.Context, relationKeys ...string) (err error) {
|
||||
func (st *SmartTest) AddRelationLinks(ctx session.Context, relationKeys ...domain.RelationKey) (err error) {
|
||||
for _, key := range relationKeys {
|
||||
st.Doc.(*state.State).AddRelationLinks(&model.RelationLink{
|
||||
Key: key,
|
||||
Key: key.String(),
|
||||
Format: 0, // todo
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *SmartTest) AddRelationLinksToState(s *state.State, relationKeys ...string) (err error) {
|
||||
func (st *SmartTest) AddRelationLinksToState(s *state.State, relationKeys ...domain.RelationKey) (err error) {
|
||||
return st.AddRelationLinks(nil, relationKeys...)
|
||||
}
|
||||
|
||||
|
@ -239,7 +237,7 @@ func (st *SmartTest) RefreshLocalDetails(ctx session.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (st *SmartTest) RemoveExtraRelations(ctx session.Context, relationKeys []string) (err error) {
|
||||
func (st *SmartTest) RemoveExtraRelations(ctx session.Context, relationKeys []domain.RelationKey) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -255,26 +253,26 @@ func (st *SmartTest) SendEvent(msgs []*pb.EventMessage) {
|
|||
return
|
||||
}
|
||||
|
||||
func (st *SmartTest) SetDetails(ctx session.Context, details []*model.Detail, showEvent bool) (err error) {
|
||||
dets := &types.Struct{Fields: map[string]*types.Value{}}
|
||||
func (st *SmartTest) SetDetails(ctx session.Context, details []domain.Detail, showEvent bool) (err error) {
|
||||
dets := domain.NewDetails()
|
||||
for _, d := range details {
|
||||
dets.Fields[d.Key] = d.Value
|
||||
dets.Set(d.Key, d.Value)
|
||||
}
|
||||
st.Doc.(*state.State).SetDetails(dets)
|
||||
return
|
||||
}
|
||||
|
||||
func (st *SmartTest) SetDetailsAndUpdateLastUsed(ctx session.Context, details []*model.Detail, showEvent bool) (err error) {
|
||||
func (st *SmartTest) SetDetailsAndUpdateLastUsed(ctx session.Context, details []domain.Detail, showEvent bool) (err error) {
|
||||
for _, detail := range details {
|
||||
st.Results.LastUsedUpdates = append(st.Results.LastUsedUpdates, detail.Key)
|
||||
st.Results.LastUsedUpdates = append(st.Results.LastUsedUpdates, string(detail.Key))
|
||||
}
|
||||
return st.SetDetails(ctx, details, showEvent)
|
||||
}
|
||||
|
||||
func (st *SmartTest) UpdateDetails(update func(current *types.Struct) (*types.Struct, error)) (err error) {
|
||||
func (st *SmartTest) UpdateDetails(update func(current *domain.Details) (*domain.Details, error)) (err error) {
|
||||
details := st.Doc.(*state.State).CombinedDetails()
|
||||
if details == nil || details.Fields == nil {
|
||||
details = &types.Struct{Fields: map[string]*types.Value{}}
|
||||
if details == nil {
|
||||
details = domain.NewDetails()
|
||||
}
|
||||
newDetails, err := update(details)
|
||||
if err != nil {
|
||||
|
@ -284,27 +282,27 @@ func (st *SmartTest) UpdateDetails(update func(current *types.Struct) (*types.St
|
|||
return nil
|
||||
}
|
||||
|
||||
func (st *SmartTest) UpdateDetailsAndLastUsed(update func(current *types.Struct) (*types.Struct, error)) (err error) {
|
||||
func (st *SmartTest) UpdateDetailsAndLastUsed(update func(current *domain.Details) (*domain.Details, error)) (err error) {
|
||||
details := st.Doc.(*state.State).CombinedDetails()
|
||||
if details == nil || details.Fields == nil {
|
||||
details = &types.Struct{Fields: map[string]*types.Value{}}
|
||||
if details == nil {
|
||||
details = domain.NewDetails()
|
||||
}
|
||||
oldDetails := pbtypes.CopyStruct(details, true)
|
||||
oldDetails := details.Copy()
|
||||
|
||||
newDetails, err := update(details)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
diff := pbtypes.StructDiff(oldDetails, newDetails)
|
||||
if diff == nil || diff.Fields == nil {
|
||||
diff := domain.StructDiff(oldDetails, newDetails)
|
||||
if diff == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
st.Doc.(*state.State).SetDetails(newDetails)
|
||||
|
||||
for key := range diff.Fields {
|
||||
st.Results.LastUsedUpdates = append(st.Results.LastUsedUpdates, key)
|
||||
for k, _ := range diff.Iterate() {
|
||||
st.Results.LastUsedUpdates = append(st.Results.LastUsedUpdates, string(k))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -360,10 +358,10 @@ func (st *SmartTest) Apply(s *state.State, flags ...smartblock.ApplyFlag) (err e
|
|||
}
|
||||
|
||||
if !keepInternalFlags {
|
||||
s.RemoveDetail(bundle.RelationKeyInternalFlags.String())
|
||||
s.RemoveDetail(bundle.RelationKeyInternalFlags)
|
||||
}
|
||||
|
||||
msgs, act, err := state.ApplyState(s, true)
|
||||
msgs, act, err := state.ApplyState(st.SpaceID(), s, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -392,7 +390,7 @@ func (st *SmartTest) History() undo.History {
|
|||
|
||||
func (st *SmartTest) StateRebuild(d state.Doc) (err error) {
|
||||
d.(*state.State).SetParent(st.Doc.(*state.State))
|
||||
_, _, err = state.ApplyState(d.(*state.State), false)
|
||||
_, _, err = state.ApplyState(st.SpaceID(), d.(*state.State), false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/anyproto/lexid"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
|
@ -20,7 +19,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/logging"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
var spaceViewLog = logging.Logger("core.block.editor.spaceview")
|
||||
|
@ -46,7 +44,7 @@ var spaceViewRequiredRelations = []domain.RelationKey{
|
|||
|
||||
type spaceService interface {
|
||||
OnViewUpdated(info spaceinfo.SpacePersistentInfo)
|
||||
OnWorkspaceChanged(spaceId string, details *types.Struct)
|
||||
OnWorkspaceChanged(spaceId string, details *domain.Details)
|
||||
PersonalSpaceId() string
|
||||
}
|
||||
|
||||
|
@ -120,16 +118,16 @@ func (s *SpaceView) initTemplate(st *state.State) {
|
|||
|
||||
func (s *SpaceView) GetExistingInviteInfo() (fileCid string, fileKey string) {
|
||||
details := s.CombinedDetails()
|
||||
fileCid = pbtypes.GetString(details, bundle.RelationKeySpaceInviteFileCid.String())
|
||||
fileKey = pbtypes.GetString(details, bundle.RelationKeySpaceInviteFileKey.String())
|
||||
fileCid = details.GetString(bundle.RelationKeySpaceInviteFileCid)
|
||||
fileKey = details.GetString(bundle.RelationKeySpaceInviteFileKey)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *SpaceView) RemoveExistingInviteInfo() (fileCid string, err error) {
|
||||
details := s.Details()
|
||||
fileCid = pbtypes.GetString(details, bundle.RelationKeySpaceInviteFileCid.String())
|
||||
fileCid = details.GetString(bundle.RelationKeySpaceInviteFileCid)
|
||||
newState := s.NewState()
|
||||
newState.RemoveDetail(bundle.RelationKeySpaceInviteFileCid.String(), bundle.RelationKeySpaceInviteFileKey.String())
|
||||
newState.RemoveDetail(bundle.RelationKeySpaceInviteFileCid, bundle.RelationKeySpaceInviteFileKey)
|
||||
return fileCid, s.Apply(newState)
|
||||
}
|
||||
|
||||
|
@ -147,26 +145,26 @@ func (s *SpaceView) SetSpaceLocalInfo(info spaceinfo.SpaceLocalInfo) (err error)
|
|||
func (s *SpaceView) SetOwner(ownerId string, createdDate int64) (err error) {
|
||||
st := s.NewState()
|
||||
if createdDate != 0 {
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyCreatedDate, pbtypes.Int64(createdDate))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyCreatedDate, domain.Int64(createdDate))
|
||||
}
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyCreator, pbtypes.String(ownerId))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyCreator, domain.String(ownerId))
|
||||
return s.Apply(st)
|
||||
}
|
||||
|
||||
func (s *SpaceView) SetAclIsEmpty(isEmpty bool) (err error) {
|
||||
st := s.NewState()
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyIsAclShared, pbtypes.Bool(!isEmpty))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeyIsAclShared, domain.Bool(!isEmpty))
|
||||
s.updateAccessType(st)
|
||||
return s.Apply(st)
|
||||
}
|
||||
|
||||
func (s *SpaceView) updateAccessType(st *state.State) {
|
||||
accessType := spaceinfo.AccessType(pbtypes.GetInt64(st.LocalDetails(), bundle.RelationKeySpaceAccessType.String()))
|
||||
accessType := spaceinfo.AccessType(st.LocalDetails().GetInt64(bundle.RelationKeySpaceAccessType))
|
||||
if accessType == spaceinfo.AccessTypePersonal {
|
||||
return
|
||||
}
|
||||
isShared := pbtypes.GetBool(st.LocalDetails(), bundle.RelationKeyIsAclShared.String())
|
||||
shareable := spaceinfo.ShareableStatus(pbtypes.GetInt64(st.LocalDetails(), bundle.RelationKeySpaceShareableStatus.String()))
|
||||
isShared := st.LocalDetails().GetBool(bundle.RelationKeyIsAclShared)
|
||||
shareable := spaceinfo.ShareableStatus(st.LocalDetails().GetInt64(bundle.RelationKeySpaceShareableStatus))
|
||||
if isShared || shareable == spaceinfo.ShareableStatusShareable {
|
||||
stateSetAccessType(st, spaceinfo.AccessTypeShared)
|
||||
} else {
|
||||
|
@ -176,11 +174,11 @@ func (s *SpaceView) updateAccessType(st *state.State) {
|
|||
|
||||
func (s *SpaceView) SetAccessType(acc spaceinfo.AccessType) (err error) {
|
||||
st := s.NewState()
|
||||
prev := spaceinfo.AccessType(pbtypes.GetInt64(st.LocalDetails(), bundle.RelationKeySpaceAccessType.String()))
|
||||
prev := spaceinfo.AccessType(st.LocalDetails().GetInt64(bundle.RelationKeySpaceAccessType))
|
||||
if prev == spaceinfo.AccessTypePersonal {
|
||||
return nil
|
||||
}
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceAccessType, pbtypes.Int64(int64(acc)))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceAccessType, domain.Int64(acc))
|
||||
return s.Apply(st)
|
||||
}
|
||||
|
||||
|
@ -192,18 +190,18 @@ func (s *SpaceView) SetSpacePersistentInfo(info spaceinfo.SpacePersistentInfo) (
|
|||
|
||||
func (s *SpaceView) SetSharedSpacesLimit(limit int) (err error) {
|
||||
st := s.NewState()
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySharedSpacesLimit, pbtypes.Int64(int64(limit)))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySharedSpacesLimit, domain.Int64(limit))
|
||||
return s.Apply(st)
|
||||
}
|
||||
|
||||
func (s *SpaceView) GetSharedSpacesLimit() (limit int) {
|
||||
return int(pbtypes.GetInt64(s.CombinedDetails(), bundle.RelationKeySharedSpacesLimit.String()))
|
||||
return int(s.CombinedDetails().GetInt64(bundle.RelationKeySharedSpacesLimit))
|
||||
}
|
||||
|
||||
func (s *SpaceView) SetInviteFileInfo(fileCid string, fileKey string) (err error) {
|
||||
st := s.NewState()
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceInviteFileCid, pbtypes.String(fileCid))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceInviteFileKey, pbtypes.String(fileKey))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceInviteFileCid, domain.String(fileCid))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceInviteFileKey, domain.String(fileKey))
|
||||
return s.Apply(st)
|
||||
}
|
||||
|
||||
|
@ -244,61 +242,56 @@ func (s *SpaceView) targetSpaceID() (id string, err error) {
|
|||
|
||||
func (s *SpaceView) getSpacePersistentInfo(st *state.State) (info spaceinfo.SpacePersistentInfo) {
|
||||
details := st.CombinedDetails()
|
||||
spaceInfo := spaceinfo.NewSpacePersistentInfo(pbtypes.GetString(details, bundle.RelationKeyTargetSpaceId.String()))
|
||||
spaceInfo.SetAccountStatus(spaceinfo.AccountStatus(pbtypes.GetInt64(details, bundle.RelationKeySpaceAccountStatus.String()))).
|
||||
SetAclHeadId(pbtypes.GetString(details, bundle.RelationKeyLatestAclHeadId.String()))
|
||||
spaceInfo := spaceinfo.NewSpacePersistentInfo(details.GetString(bundle.RelationKeyTargetSpaceId))
|
||||
spaceInfo.SetAccountStatus(spaceinfo.AccountStatus(details.GetInt64(bundle.RelationKeySpaceAccountStatus))).
|
||||
SetAclHeadId(details.GetString(bundle.RelationKeyLatestAclHeadId))
|
||||
return spaceInfo
|
||||
}
|
||||
|
||||
var workspaceKeysToCopy = []string{
|
||||
bundle.RelationKeyName.String(),
|
||||
bundle.RelationKeyIconImage.String(),
|
||||
bundle.RelationKeyIconOption.String(),
|
||||
bundle.RelationKeySpaceDashboardId.String(),
|
||||
bundle.RelationKeyCreatedDate.String(),
|
||||
bundle.RelationKeyChatId.String(),
|
||||
var workspaceKeysToCopy = []domain.RelationKey{
|
||||
bundle.RelationKeyName,
|
||||
bundle.RelationKeyIconImage,
|
||||
bundle.RelationKeyIconOption,
|
||||
bundle.RelationKeySpaceDashboardId,
|
||||
bundle.RelationKeyCreatedDate,
|
||||
bundle.RelationKeyChatId,
|
||||
}
|
||||
|
||||
func (s *SpaceView) GetSpaceDescription() (data spaceinfo.SpaceDescription) {
|
||||
details := s.CombinedDetails()
|
||||
data.Name = pbtypes.GetString(details, bundle.RelationKeyName.String())
|
||||
data.IconImage = pbtypes.GetString(details, bundle.RelationKeyIconImage.String())
|
||||
data.Name = details.GetString(bundle.RelationKeyName)
|
||||
data.IconImage = details.GetString(bundle.RelationKeyIconImage)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *SpaceView) SetSpaceData(details *types.Struct) error {
|
||||
func (s *SpaceView) SetSpaceData(details *domain.Details) error {
|
||||
st := s.NewState()
|
||||
var changed bool
|
||||
for k, v := range details.Fields {
|
||||
for k, v := range details.Iterate() {
|
||||
if slices.Contains(workspaceKeysToCopy, k) {
|
||||
// Special case for migration to Files as Objects to handle following situation:
|
||||
// - We have an icon in Workspace that was created in pre-Files as Objects version
|
||||
// - We migrate it, change old id to new id
|
||||
// - Now we need to push details to SpaceView. But if we push NEW id, then old clients will not be able to display image
|
||||
// - So we need to push old id
|
||||
if k == bundle.RelationKeyIconImage.String() {
|
||||
fileId, err := s.fileObjectService.GetFileIdFromObject(v.GetStringValue())
|
||||
if k == bundle.RelationKeyIconImage {
|
||||
fileId, err := s.fileObjectService.GetFileIdFromObject(v.String())
|
||||
if err == nil {
|
||||
switch v.Kind.(type) {
|
||||
case *types.Value_StringValue:
|
||||
v = pbtypes.String(fileId.FileId.String())
|
||||
case *types.Value_ListValue:
|
||||
v = pbtypes.StringList([]string{fileId.FileId.String()})
|
||||
}
|
||||
v = domain.String(fileId.FileId.String())
|
||||
}
|
||||
}
|
||||
if k == bundle.RelationKeyCreatedDate.String() && s.GetLocalInfo().SpaceId != s.spaceService.PersonalSpaceId() {
|
||||
if k == bundle.RelationKeyCreatedDate && s.GetLocalInfo().SpaceId != s.spaceService.PersonalSpaceId() {
|
||||
continue
|
||||
}
|
||||
changed = true
|
||||
st.SetDetailAndBundledRelation(domain.RelationKey(k), v)
|
||||
st.SetDetailAndBundledRelation(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
if changed {
|
||||
if st.ParentState().ParentState() == nil {
|
||||
// in case prev change was the first one
|
||||
createdDate := pbtypes.GetInt64(details, bundle.RelationKeyCreatedDate.String())
|
||||
createdDate := details.GetInt64(bundle.RelationKeyCreatedDate)
|
||||
if createdDate > 0 {
|
||||
// we use this state field to save the original created date, otherwise we use the one from the underlying objectTree
|
||||
st.SetOriginalCreatedTimestamp(createdDate)
|
||||
|
@ -312,23 +305,23 @@ func (s *SpaceView) SetSpaceData(details *types.Struct) error {
|
|||
|
||||
func (s *SpaceView) UpdateLastOpenedDate() error {
|
||||
st := s.NewState()
|
||||
st.SetLocalDetail(bundle.RelationKeyLastOpenedDate.String(), pbtypes.Int64(time.Now().Unix()))
|
||||
st.SetLocalDetail(bundle.RelationKeyLastOpenedDate, domain.Int64(time.Now().Unix()))
|
||||
return s.Apply(st, smartblock.NoHistory, smartblock.NoEvent, smartblock.SkipIfNoChanges, smartblock.KeepInternalFlags)
|
||||
}
|
||||
|
||||
func (s *SpaceView) SetOrder(prevViewOrderId string) (string, error) {
|
||||
st := s.NewState()
|
||||
spaceOrderId := lx.Next(prevViewOrderId)
|
||||
st.SetDetail(bundle.RelationKeySpaceOrder.String(), pbtypes.String(spaceOrderId))
|
||||
st.SetDetail(bundle.RelationKeySpaceOrder, domain.String(spaceOrderId))
|
||||
return spaceOrderId, s.Apply(st)
|
||||
}
|
||||
|
||||
func (s *SpaceView) SetAfterGivenView(viewOrderId string) error {
|
||||
st := s.NewState()
|
||||
spaceOrderId := pbtypes.GetString(st.Details(), bundle.RelationKeySpaceOrder.String())
|
||||
spaceOrderId := st.Details().GetString(bundle.RelationKeySpaceOrder)
|
||||
if viewOrderId > spaceOrderId {
|
||||
spaceOrderId = lx.Next(viewOrderId)
|
||||
st.SetDetail(bundle.RelationKeySpaceOrder.String(), pbtypes.String(spaceOrderId))
|
||||
st.SetDetail(bundle.RelationKeySpaceOrder, domain.String(spaceOrderId))
|
||||
return s.Apply(st)
|
||||
}
|
||||
return nil
|
||||
|
@ -340,10 +333,10 @@ func (s *SpaceView) SetBetweenViews(prevViewOrderId, afterViewOrderId string) er
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to get before lexid, %w", err)
|
||||
}
|
||||
st.SetDetail(bundle.RelationKeySpaceOrder.String(), pbtypes.String(before))
|
||||
st.SetDetail(bundle.RelationKeySpaceOrder, domain.String(before))
|
||||
return s.Apply(st)
|
||||
}
|
||||
|
||||
func stateSetAccessType(st *state.State, accessType spaceinfo.AccessType) {
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceAccessType, pbtypes.Int64(int64(accessType)))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceAccessType, domain.Int64(accessType))
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
@ -13,10 +12,10 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest"
|
||||
"github.com/anyproto/anytype-heart/core/block/migration"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func TestSpaceView_AccessType(t *testing.T) {
|
||||
|
@ -125,8 +124,8 @@ func TestSpaceView_SetOwner(t *testing.T) {
|
|||
defer fx.finish()
|
||||
err := fx.SetOwner("ownerId", 125)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "ownerId", pbtypes.GetString(fx.CombinedDetails(), bundle.RelationKeyCreator.String()))
|
||||
require.Equal(t, int64(125), pbtypes.GetInt64(fx.CombinedDetails(), bundle.RelationKeyCreatedDate.String()))
|
||||
require.Equal(t, "ownerId", fx.CombinedDetails().GetString(bundle.RelationKeyCreator))
|
||||
require.Equal(t, int64(125), fx.CombinedDetails().GetInt64(bundle.RelationKeyCreatedDate))
|
||||
}
|
||||
|
||||
func TestSpaceView_SetAfterGivenView(t *testing.T) {
|
||||
|
@ -140,14 +139,14 @@ func TestSpaceView_SetAfterGivenView(t *testing.T) {
|
|||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
|
||||
assert.NotEmpty(t, fx.Details().GetString(bundle.RelationKeySpaceOrder))
|
||||
})
|
||||
t.Run("set view after given id, order exist", func(t *testing.T) {
|
||||
// given
|
||||
fx := newSpaceViewFixture(t)
|
||||
defer fx.finish()
|
||||
state := fx.NewState()
|
||||
state.SetDetail(bundle.RelationKeySpaceOrder.String(), pbtypes.String("spaceViewOrderId"))
|
||||
state.SetDetail(bundle.RelationKeySpaceOrder, domain.String("spaceViewOrderId"))
|
||||
err := fx.Apply(state)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -156,15 +155,15 @@ func TestSpaceView_SetAfterGivenView(t *testing.T) {
|
|||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
assert.NotEqual(t, "spaceViewOrderId", pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
|
||||
assert.True(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()) > "viewOrderId")
|
||||
assert.NotEqual(t, "spaceViewOrderId", fx.Details().GetString(bundle.RelationKeySpaceOrder))
|
||||
assert.True(t, fx.Details().GetString(bundle.RelationKeySpaceOrder) > "viewOrderId")
|
||||
})
|
||||
t.Run("set view after given id, order exist, but already less than given view", func(t *testing.T) {
|
||||
// given
|
||||
fx := newSpaceViewFixture(t)
|
||||
defer fx.finish()
|
||||
state := fx.NewState()
|
||||
state.SetDetail(bundle.RelationKeySpaceOrder.String(), pbtypes.String("viewOrderId"))
|
||||
state.SetDetail(bundle.RelationKeySpaceOrder, domain.String("viewOrderId"))
|
||||
err := fx.Apply(state)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -173,8 +172,8 @@ func TestSpaceView_SetAfterGivenView(t *testing.T) {
|
|||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "viewOrderId", pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
|
||||
assert.True(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()) > "spaceViewOrderId")
|
||||
assert.Equal(t, "viewOrderId", fx.Details().GetString(bundle.RelationKeySpaceOrder))
|
||||
assert.True(t, fx.Details().GetString(bundle.RelationKeySpaceOrder) > "spaceViewOrderId")
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -189,7 +188,7 @@ func TestSpaceView_SetBetweenViews(t *testing.T) {
|
|||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
|
||||
assert.NotEmpty(t, fx.Details().GetString(bundle.RelationKeySpaceOrder))
|
||||
})
|
||||
t.Run("set view between", func(t *testing.T) {
|
||||
// given
|
||||
|
@ -204,7 +203,7 @@ func TestSpaceView_SetBetweenViews(t *testing.T) {
|
|||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
|
||||
assert.NotEmpty(t, fx.Details().GetString(bundle.RelationKeySpaceOrder))
|
||||
})
|
||||
t.Run("after id is empty", func(t *testing.T) {
|
||||
// given
|
||||
|
@ -231,9 +230,9 @@ func TestSpaceView_SetOrder(t *testing.T) {
|
|||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
|
||||
assert.Equal(t, order, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
|
||||
assert.True(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()) > prevViewOrderId)
|
||||
assert.NotEmpty(t, fx.Details().GetString(bundle.RelationKeySpaceOrder))
|
||||
assert.Equal(t, order, fx.Details().GetString(bundle.RelationKeySpaceOrder))
|
||||
assert.True(t, fx.Details().GetString(bundle.RelationKeySpaceOrder) > prevViewOrderId)
|
||||
})
|
||||
t.Run("set order, previous id not empty", func(t *testing.T) {
|
||||
// given
|
||||
|
@ -246,9 +245,9 @@ func TestSpaceView_SetOrder(t *testing.T) {
|
|||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
|
||||
assert.Equal(t, order, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
|
||||
assert.True(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()) > prevViewOrderId)
|
||||
assert.NotEmpty(t, fx.Details().GetString(bundle.RelationKeySpaceOrder))
|
||||
assert.Equal(t, order, fx.Details().GetString(bundle.RelationKeySpaceOrder))
|
||||
assert.True(t, fx.Details().GetString(bundle.RelationKeySpaceOrder) > prevViewOrderId)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -262,7 +261,7 @@ func (s *spaceServiceStub) PersonalSpaceId() string {
|
|||
func (s *spaceServiceStub) OnViewUpdated(info spaceinfo.SpacePersistentInfo) {
|
||||
}
|
||||
|
||||
func (s *spaceServiceStub) OnWorkspaceChanged(spaceId string, details *types.Struct) {
|
||||
func (s *spaceServiceStub) OnWorkspaceChanged(spaceId string, details *domain.Details) {
|
||||
}
|
||||
|
||||
func NewSpaceViewTest(t *testing.T, targetSpaceId string, tree *mock_objecttree.MockObjectTree) (*SpaceView, error) {
|
||||
|
@ -314,7 +313,7 @@ func newSpaceViewFixture(t *testing.T) *spaceViewFixture {
|
|||
}
|
||||
|
||||
func (f *spaceViewFixture) getAccessType() spaceinfo.AccessType {
|
||||
return spaceinfo.AccessType(pbtypes.GetInt64(f.CombinedDetails(), bundle.RelationKeySpaceAccessType.String()))
|
||||
return spaceinfo.AccessType(f.CombinedDetails().GetInt64(bundle.RelationKeySpaceAccessType))
|
||||
}
|
||||
|
||||
func (f *spaceViewFixture) finish() {
|
||||
|
|
|
@ -5,8 +5,6 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/mb0/diff"
|
||||
"golang.org/x/exp/slices"
|
||||
|
@ -16,7 +14,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/relationutils"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/addr"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
|
@ -24,13 +21,8 @@ import (
|
|||
)
|
||||
|
||||
type snapshotOptions struct {
|
||||
changeId string
|
||||
internalKey string
|
||||
uniqueKeyMigration *uniqueKeyMigration
|
||||
}
|
||||
|
||||
type uniqueKeyMigration struct {
|
||||
sbType smartblock.SmartBlockType
|
||||
changeId string
|
||||
internalKey string
|
||||
}
|
||||
|
||||
type SnapshotOption func(*snapshotOptions)
|
||||
|
@ -48,17 +40,6 @@ func WithInternalKey(internalKey string) func(*snapshotOptions) {
|
|||
}
|
||||
}
|
||||
|
||||
// WithUniqueKeyMigration tries to extract unique key from id of supported legacy objects.
|
||||
// For example, legacy object type has id "ot-page", so unique key will be "ot-page".
|
||||
// The full list of supported objects you can see in documentation near domain.UniqueKey
|
||||
func WithUniqueKeyMigration(sbType smartblock.SmartBlockType) func(*snapshotOptions) {
|
||||
return func(o *snapshotOptions) {
|
||||
o.uniqueKeyMigration = &uniqueKeyMigration{
|
||||
sbType: sbType,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewDocFromSnapshot(rootId string, snapshot *pb.ChangeSnapshot, opts ...SnapshotOption) Doc {
|
||||
sOpts := snapshotOptions{}
|
||||
for _, opt := range opts {
|
||||
|
@ -81,22 +62,19 @@ func NewDocFromSnapshot(rootId string, snapshot *pb.ChangeSnapshot, opts ...Snap
|
|||
removedCollectionKeysMap[t] = struct{}{}
|
||||
}
|
||||
|
||||
detailsToSave := pbtypes.StructCutKeys(snapshot.Data.Details, bundle.LocalAndDerivedRelationKeys)
|
||||
|
||||
if err := pbtypes.ValidateStruct(detailsToSave); err != nil {
|
||||
detailsFromSnapshot := pbtypes.StructCutKeys(snapshot.Data.Details, slice.IntoStrings(bundle.LocalAndDerivedRelationKeys))
|
||||
if err := pbtypes.ValidateStruct(detailsFromSnapshot); err != nil {
|
||||
log.Errorf("NewDocFromSnapshot details validation error: %v; details normalized", err)
|
||||
pbtypes.NormalizeStruct(detailsToSave)
|
||||
pbtypes.NormalizeStruct(detailsFromSnapshot)
|
||||
}
|
||||
|
||||
if sOpts.uniqueKeyMigration != nil {
|
||||
migrateAddMissingUniqueKey(sOpts.uniqueKeyMigration.sbType, snapshot)
|
||||
}
|
||||
details := domain.NewDetailsFromProto(detailsFromSnapshot)
|
||||
|
||||
s := &State{
|
||||
changeId: sOpts.changeId,
|
||||
rootId: rootId,
|
||||
blocks: blocks,
|
||||
details: detailsToSave,
|
||||
details: details,
|
||||
relationLinks: snapshot.Data.RelationLinks,
|
||||
objectTypeKeys: migrateObjectTypeIDsToKeys(snapshot.Data.ObjectTypes),
|
||||
fileKeys: fileKeys,
|
||||
|
@ -126,9 +104,9 @@ func NewDocFromSnapshot(rootId string, snapshot *pb.ChangeSnapshot, opts ...Snap
|
|||
|
||||
func (s *State) SetLastModified(ts int64, identityLink string) {
|
||||
if ts > 0 {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyLastModifiedDate, pbtypes.Int64(ts))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyLastModifiedDate, domain.Int64(ts))
|
||||
}
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyLastModifiedBy, pbtypes.String(identityLink))
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyLastModifiedBy, domain.String(identityLink))
|
||||
}
|
||||
|
||||
func (s *State) SetChangeId(id string) {
|
||||
|
@ -263,35 +241,31 @@ func (s *State) applyChange(ch *pb.ChangeContent) (err error) {
|
|||
|
||||
func (s *State) changeBlockDetailsSet(set *pb.ChangeDetailsSet) error {
|
||||
det := s.Details()
|
||||
if det == nil || det.Fields == nil {
|
||||
det = &types.Struct{
|
||||
Fields: make(map[string]*types.Value),
|
||||
}
|
||||
if det == nil {
|
||||
det = domain.NewDetails()
|
||||
}
|
||||
// TODO: GO-2062 Need to refactor details shortening, as it could cut string incorrectly
|
||||
// set.Value = shortenValueToLimit(s.rootId, set.Key, set.Value)
|
||||
if s.details == nil || s.details.Fields == nil {
|
||||
s.details = pbtypes.CopyStruct(det, false)
|
||||
if s.details == nil {
|
||||
s.details = det.Copy()
|
||||
}
|
||||
if set.Value != nil {
|
||||
s.details.Fields[set.Key] = set.Value
|
||||
s.details.SetProtoValue(domain.RelationKey(set.Key), set.Value)
|
||||
} else {
|
||||
delete(s.details.Fields, set.Key)
|
||||
s.details.Delete(domain.RelationKey(set.Key))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *State) changeBlockDetailsUnset(unset *pb.ChangeDetailsUnset) error {
|
||||
det := s.Details()
|
||||
if det == nil || det.Fields == nil {
|
||||
det = &types.Struct{
|
||||
Fields: make(map[string]*types.Value),
|
||||
}
|
||||
if det == nil {
|
||||
det = domain.NewDetails()
|
||||
}
|
||||
if s.details == nil || s.details.Fields == nil {
|
||||
s.details = pbtypes.CopyStruct(det, false)
|
||||
if s.details == nil {
|
||||
s.details = det.Copy()
|
||||
}
|
||||
delete(s.details.Fields, unset.Key)
|
||||
s.details.Delete(domain.RelationKey(unset.Key))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -307,7 +281,7 @@ func (s *State) changeRelationAdd(add *pb.ChangeRelationAdd) error {
|
|||
}
|
||||
|
||||
func (s *State) changeRelationRemove(rem *pb.ChangeRelationRemove) error {
|
||||
s.RemoveRelation(rem.RelationKey...)
|
||||
s.RemoveRelation(slice.StringsInto[domain.RelationKey](rem.RelationKey)...)
|
||||
return nil
|
||||
}
|
||||
func migrateObjectTypeIDToKey(old string) (new string) {
|
||||
|
@ -646,7 +620,7 @@ func (s *State) fillChanges(msgs []simple.EventMessage) {
|
|||
func (s *State) filterLocalAndDerivedRelations(newRelLinks pbtypes.RelationLinks) pbtypes.RelationLinks {
|
||||
var relLinksWithoutLocal pbtypes.RelationLinks
|
||||
for _, link := range newRelLinks {
|
||||
if !slices.Contains(bundle.LocalAndDerivedRelationKeys, link.Key) {
|
||||
if !slices.Contains(bundle.LocalAndDerivedRelationKeys, domain.RelationKey(link.Key)) {
|
||||
relLinksWithoutLocal = relLinksWithoutLocal.Append(link)
|
||||
}
|
||||
}
|
||||
|
@ -656,7 +630,7 @@ func (s *State) filterLocalAndDerivedRelations(newRelLinks pbtypes.RelationLinks
|
|||
func (s *State) filterLocalAndDerivedRelationsByKey(relationKeys []string) []string {
|
||||
var relKeysWithoutLocal []string
|
||||
for _, key := range relationKeys {
|
||||
if !slices.Contains(bundle.LocalAndDerivedRelationKeys, key) {
|
||||
if !slices.Contains(bundle.LocalAndDerivedRelationKeys, domain.RelationKey(key)) {
|
||||
relKeysWithoutLocal = append(relKeysWithoutLocal, key)
|
||||
}
|
||||
}
|
||||
|
@ -725,36 +699,39 @@ func (s *State) makeStructureChanges(cb *changeBuilder, msg *pb.EventBlockSetChi
|
|||
}
|
||||
|
||||
func (s *State) makeDetailsChanges() (ch []*pb.ChangeContent) {
|
||||
if s.details == nil || s.details.Fields == nil {
|
||||
if s.details == nil {
|
||||
return nil
|
||||
}
|
||||
var prev *types.Struct
|
||||
var prev *domain.Details
|
||||
if s.parent != nil {
|
||||
prev = s.parent.Details()
|
||||
}
|
||||
if prev == nil || prev.Fields == nil {
|
||||
prev = &types.Struct{Fields: make(map[string]*types.Value)}
|
||||
if prev == nil {
|
||||
prev = domain.NewDetails()
|
||||
}
|
||||
curDetails := s.Details()
|
||||
for k, v := range curDetails.Fields {
|
||||
pv, ok := prev.Fields[k]
|
||||
if !ok || !pv.Equal(v) {
|
||||
|
||||
for k, v := range curDetails.Iterate() {
|
||||
prevValue := prev.Get(k)
|
||||
if !prevValue.Ok() || !prevValue.Equal(v) {
|
||||
ch = append(ch, &pb.ChangeContent{
|
||||
Value: &pb.ChangeContentValueOfDetailsSet{
|
||||
DetailsSet: &pb.ChangeDetailsSet{Key: k, Value: v},
|
||||
DetailsSet: &pb.ChangeDetailsSet{Key: string(k), Value: v.ToProto()},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
for k := range prev.Fields {
|
||||
if _, ok := curDetails.Fields[k]; !ok {
|
||||
|
||||
for k, _ := range prev.Iterate() {
|
||||
if !curDetails.Has(k) {
|
||||
ch = append(ch, &pb.ChangeContent{
|
||||
Value: &pb.ChangeContentValueOfDetailsUnset{
|
||||
DetailsUnset: &pb.ChangeDetailsUnset{Key: k},
|
||||
DetailsUnset: &pb.ChangeDetailsUnset{Key: string(k)},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -990,24 +967,3 @@ func migrateObjectTypeIDsToKeys(objectTypeIDs []string) []domain.TypeKey {
|
|||
}
|
||||
return objectTypeKeys
|
||||
}
|
||||
|
||||
// Adds missing unique key for supported smartblock types
|
||||
func migrateAddMissingUniqueKey(sbType smartblock.SmartBlockType, snapshot *pb.ChangeSnapshot) {
|
||||
id := pbtypes.GetString(snapshot.Data.Details, bundle.RelationKeyId.String())
|
||||
uk, err := domain.UnmarshalUniqueKey(id)
|
||||
if err != nil {
|
||||
// Maybe it's a relation option?
|
||||
if bson.IsObjectIdHex(id) {
|
||||
uk = domain.MustUniqueKey(smartblock.SmartBlockTypeRelationOption, id)
|
||||
} else {
|
||||
// Means that smartblock type is not supported
|
||||
return
|
||||
}
|
||||
}
|
||||
if uk.SmartblockType() != sbType {
|
||||
log.Errorf("missingKeyMigration: wrong sbtype %s != %s", uk.SmartblockType(), sbType)
|
||||
return
|
||||
}
|
||||
|
||||
snapshot.Data.Key = uk.InternalKey()
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ func TestState_ChangesCreate_MoveAdd(t *testing.T) {
|
|||
require.NoError(t, s.InsertTo("b", model.Block_Inner, "1", "2", "4", "5"))
|
||||
s.Add(simple.New(&model.Block{Id: "3.1"}))
|
||||
require.NoError(t, s.InsertTo("2", model.Block_Bottom, "3.1"))
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
changes := d.(*State).GetChanges()
|
||||
require.Len(t, changes, 4)
|
||||
|
@ -62,7 +62,7 @@ func TestState_ChangesCreate_Collection_Set(t *testing.T) {
|
|||
d := NewDoc("root", nil)
|
||||
s := d.NewState()
|
||||
s.SetInStore([]string{"coll1", "key1"}, pbtypes.String("1"))
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
changes := d.(*State).GetChanges()
|
||||
require.Len(t, changes, 1)
|
||||
|
@ -81,7 +81,7 @@ func TestState_ChangesCreate_Collection_Unset(t *testing.T) {
|
|||
d.(*State).store = makeStoreWithTwoKeysAndValue("coll1", "key1", "1")
|
||||
s := d.NewState()
|
||||
s.RemoveFromStore([]string{"coll1", "key1"})
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
changes := d.(*State).GetChanges()
|
||||
require.Len(t, changes, 1)
|
||||
|
@ -197,7 +197,7 @@ func TestState_ChangesCreate_StoreSlice(t *testing.T) {
|
|||
newState := doc.NewState()
|
||||
newState.UpdateStoreSlice(key, tc.after)
|
||||
|
||||
_, _, err := ApplyState(newState, false)
|
||||
_, _, err := ApplyState("", newState, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
got := doc.(*State).GetChanges()
|
||||
|
@ -232,12 +232,12 @@ func TestState_ChangesCreate_MoveAdd_Wrap(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "div", ChildrenIds: []string{"a", "b"}}))
|
||||
s.Get("root").Model().ChildrenIds = []string{"div"}
|
||||
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
changes := d.(*State).GetChanges()
|
||||
s2 := dc.NewState()
|
||||
require.NoError(t, s2.ApplyChange(changes...))
|
||||
_, _, err = ApplyState(s2, true)
|
||||
_, _, err = ApplyState("", s2, true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, d.(*State).String(), dc.(*State).String())
|
||||
}
|
||||
|
@ -264,12 +264,12 @@ func TestState_ChangesCreate_MoveAdd_Side(t *testing.T) {
|
|||
s.Unlink("5")
|
||||
s.InsertTo("1", model.Block_Left, "4", "5")
|
||||
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
changes := d.(*State).GetChanges()
|
||||
s2 := dc.NewState()
|
||||
require.NoError(t, s2.ApplyChange(changes...))
|
||||
_, _, err = ApplyState(s2, true)
|
||||
_, _, err = ApplyState("", s2, true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, d.(*State).String(), dc.(*State).String())
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ func TestState_ChangesCreate_MoveAdd_Side_NewBlock(t *testing.T) {
|
|||
assertApplyingChanges := func(t *testing.T, state *State, wantState *State, originalState *State) {
|
||||
AssertTreesEqual(t, wantState.Blocks(), state.Blocks())
|
||||
|
||||
_, _, err := ApplyState(state, true)
|
||||
_, _, err := ApplyState("", state, true)
|
||||
require.NoError(t, err)
|
||||
changes := state.GetChanges()
|
||||
err = originalState.ApplyChange(changes...)
|
||||
|
@ -368,11 +368,12 @@ func TestState_SetParent(t *testing.T) {
|
|||
|
||||
ns.SetRootId(st.RootId())
|
||||
ns.SetParent(st)
|
||||
_, _, err := ApplyState(ns, false)
|
||||
_, _, err := ApplyState("", ns, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
st2 := orig.Copy()
|
||||
require.NoError(t, st2.ApplyChange(st.GetChanges()...))
|
||||
|
||||
assert.Equal(t, st.StringDebug(), st2.StringDebug())
|
||||
}
|
||||
|
||||
|
@ -391,7 +392,7 @@ func TestStateNormalizeMerge(t *testing.T) {
|
|||
s.InsertTo(fmt.Sprintf("common%d", i-1), model.Block_Bottom, id)
|
||||
}
|
||||
}
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("parallel normalize", func(t *testing.T) {
|
||||
|
@ -402,7 +403,7 @@ func TestStateNormalizeMerge(t *testing.T) {
|
|||
stateA.Add(simple.New(&model.Block{Id: "a1"}))
|
||||
stateA.Add(simple.New(&model.Block{Id: "a2"}))
|
||||
stateA.InsertTo("common39", model.Block_Bottom, "a1", "a2")
|
||||
_, _, err = ApplyState(stateA, true)
|
||||
_, _, err = ApplyState("", stateA, true)
|
||||
require.NoError(t, err)
|
||||
// t.Log(docA.String())
|
||||
changesA := stateA.GetChanges()
|
||||
|
@ -411,18 +412,18 @@ func TestStateNormalizeMerge(t *testing.T) {
|
|||
stateB := docB.NewState()
|
||||
stateB.Add(simple.New(&model.Block{Id: "b1"}))
|
||||
stateB.InsertTo("common39", model.Block_Bottom, "b1")
|
||||
_, _, err = ApplyState(stateB, true)
|
||||
_, _, err = ApplyState("", stateB, true)
|
||||
require.NoError(t, err)
|
||||
// t.Log(docB.String())
|
||||
changesB := stateB.GetChanges()
|
||||
|
||||
s = d.NewState()
|
||||
require.NoError(t, s.ApplyChange(changesB...))
|
||||
_, _, err = ApplyStateFastOne(s)
|
||||
_, _, err = ApplyStateFastOne("", s)
|
||||
require.NoError(t, err)
|
||||
s = d.NewState()
|
||||
require.NoError(t, s.ApplyChange(changesA...))
|
||||
_, _, err = ApplyState(s, true)
|
||||
_, _, err = ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
s = d.NewState()
|
||||
|
@ -438,7 +439,7 @@ func TestStateNormalizeMerge(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "common40"}))
|
||||
s.InsertTo("common39", model.Block_Bottom, "common40")
|
||||
ids = append(ids, "common40")
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
aIds := []string{}
|
||||
|
@ -450,7 +451,7 @@ func TestStateNormalizeMerge(t *testing.T) {
|
|||
stateA.Add(simple.New(&model.Block{Id: id}))
|
||||
}
|
||||
stateA.InsertTo("common0", model.Block_Top, aIds...)
|
||||
_, _, err = ApplyState(stateA, true)
|
||||
_, _, err = ApplyState("", stateA, true)
|
||||
require.NoError(t, err)
|
||||
changesA := stateA.GetChanges()
|
||||
|
||||
|
@ -463,17 +464,17 @@ func TestStateNormalizeMerge(t *testing.T) {
|
|||
stateB.Add(simple.New(&model.Block{Id: id}))
|
||||
}
|
||||
stateB.InsertTo("common40", model.Block_Bottom, bIds...)
|
||||
_, _, err = ApplyState(stateB, true)
|
||||
_, _, err = ApplyState("", stateB, true)
|
||||
require.NoError(t, err)
|
||||
changesB := stateB.GetChanges()
|
||||
|
||||
s = d.NewState()
|
||||
require.NoError(t, s.ApplyChange(changesB...))
|
||||
_, _, err = ApplyStateFastOne(s)
|
||||
_, _, err = ApplyStateFastOne("", s)
|
||||
require.NoError(t, err)
|
||||
s = d.NewState()
|
||||
require.NoError(t, s.ApplyChange(changesA...))
|
||||
_, _, err = ApplyState(s, true)
|
||||
_, _, err = ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
s = d.NewState()
|
||||
|
@ -505,12 +506,12 @@ func TestState_ChangeDataviewOrder(t *testing.T) {
|
|||
s := d.NewState()
|
||||
s.Get("dv").(dataview.Block).SetViewOrder([]string{"3", "1", "2"})
|
||||
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
changes := d.(*State).GetChanges()
|
||||
s2 := dc.NewState()
|
||||
require.NoError(t, s2.ApplyChange(changes...))
|
||||
_, _, err = ApplyState(s2, true)
|
||||
_, _, err = ApplyState("", s2, true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, d.(*State).Pick("dv").Model().String(), dc.(*State).Pick("dv").Model().String())
|
||||
}
|
||||
|
@ -533,11 +534,11 @@ func TestState_ChangeDataviewUnlink(t *testing.T) {
|
|||
},
|
||||
}}))
|
||||
s.InsertTo("root", model.Block_Inner, "dv")
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
changes := d.(*State).GetChanges()
|
||||
s = d.NewState()
|
||||
s.Unlink("dv")
|
||||
_, _, err = ApplyState(s, true)
|
||||
_, _, err = ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
changes = append(changes, d.(*State).GetChanges()...)
|
||||
|
||||
|
@ -546,7 +547,7 @@ func TestState_ChangeDataviewUnlink(t *testing.T) {
|
|||
require.Nil(t, s2.Get("dv"))
|
||||
require.Nil(t, s2.Pick("dv"))
|
||||
|
||||
_, _, err = ApplyState(s2, true)
|
||||
_, _, err = ApplyState("", s2, true)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, dc.(*State).Get("dv"))
|
||||
require.Nil(t, dc.(*State).Pick("dv"))
|
||||
|
@ -570,11 +571,11 @@ func TestState_ChangeDataviewRemoveAdd(t *testing.T) {
|
|||
},
|
||||
}}))
|
||||
s.InsertTo("root", model.Block_Inner, "dv")
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
changes := d.(*State).GetChanges()
|
||||
s = d.NewState()
|
||||
s.Unlink("dv")
|
||||
_, _, err = ApplyState(s, true)
|
||||
_, _, err = ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
changes = append(changes, d.(*State).GetChanges()...)
|
||||
s = d.NewState()
|
||||
|
@ -586,7 +587,7 @@ func TestState_ChangeDataviewRemoveAdd(t *testing.T) {
|
|||
},
|
||||
}}))
|
||||
s.InsertTo("root", model.Block_Inner, "dv")
|
||||
_, _, err = ApplyState(s, true)
|
||||
_, _, err = ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
changes = append(changes, d.(*State).GetChanges()...)
|
||||
|
@ -596,7 +597,7 @@ func TestState_ChangeDataviewRemoveAdd(t *testing.T) {
|
|||
require.Len(t, s2.Get("dv").Model().GetDataview().Views, 1)
|
||||
require.Equal(t, "2", s2.Get("dv").Model().GetDataview().Views[0].Id)
|
||||
|
||||
_, _, err = ApplyState(s2, true)
|
||||
_, _, err = ApplyState("", s2, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, dc.(*State).Get("dv"))
|
||||
require.Len(t, dc.(*State).Get("dv").Model().GetDataview().Views, 1)
|
||||
|
@ -623,7 +624,7 @@ func TestState_ChangeDataviewRemoveMove(t *testing.T) {
|
|||
|
||||
s := d1.NewState()
|
||||
require.NoError(t, s.ApplyChange(changes...))
|
||||
ApplyState(s, true)
|
||||
ApplyState("", s, true)
|
||||
require.Nil(t, d1.(*State).blocks["b"])
|
||||
require.NotContains(t, d1.(*State).Pick("s").Model().ChildrenIds, "b")
|
||||
require.NotContains(t, d1.(*State).Pick("root").Model().ChildrenIds, "b")
|
||||
|
@ -692,7 +693,7 @@ func TestRelationChanges(t *testing.T) {
|
|||
ac := a.Copy()
|
||||
b := a.NewState()
|
||||
b.relationLinks = []*model.RelationLink{{Key: "3"}, {Key: "4"}, {Key: "5"}}
|
||||
_, _, err := ApplyState(b, false)
|
||||
_, _, err := ApplyState("", b, false)
|
||||
require.NoError(t, err)
|
||||
chs := a.GetChanges()
|
||||
require.NoError(t, ac.ApplyChange(chs...))
|
||||
|
@ -708,7 +709,7 @@ func TestLocalRelationChanges(t *testing.T) {
|
|||
b.relationLinks = []*model.RelationLink{{Key: bundle.RelationKeySyncStatus.String(), Format: model.RelationFormat_number}}
|
||||
|
||||
// when
|
||||
_, _, err := ApplyState(b, false)
|
||||
_, _, err := ApplyState("", b, false)
|
||||
require.NoError(t, err)
|
||||
chs := a.GetChanges()
|
||||
|
||||
|
@ -723,7 +724,7 @@ func TestLocalRelationChanges(t *testing.T) {
|
|||
b.relationLinks = []*model.RelationLink{}
|
||||
|
||||
// when
|
||||
_, _, err := ApplyState(b, false)
|
||||
_, _, err := ApplyState("", b, false)
|
||||
require.NoError(t, err)
|
||||
chs := a.GetChanges()
|
||||
|
||||
|
@ -738,7 +739,7 @@ func TestLocalRelationChanges(t *testing.T) {
|
|||
b.relationLinks = []*model.RelationLink{{Key: bundle.RelationKeySpaceId.String(), Format: model.RelationFormat_longtext}}
|
||||
|
||||
// when
|
||||
_, _, err := ApplyState(b, false)
|
||||
_, _, err := ApplyState("", b, false)
|
||||
require.NoError(t, err)
|
||||
chs := a.GetChanges()
|
||||
|
||||
|
@ -753,7 +754,7 @@ func TestLocalRelationChanges(t *testing.T) {
|
|||
b.relationLinks = []*model.RelationLink{}
|
||||
|
||||
// when
|
||||
_, _, err := ApplyState(b, false)
|
||||
_, _, err := ApplyState("", b, false)
|
||||
require.NoError(t, err)
|
||||
chs := a.GetChanges()
|
||||
|
||||
|
@ -769,7 +770,7 @@ func TestRootBlockChanges(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "new"}))
|
||||
require.NoError(t, s.InsertTo("root", model.Block_Inner, "new"))
|
||||
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
changes := s.GetChanges()
|
||||
|
||||
|
@ -825,7 +826,7 @@ func buildStateFromAST(root *Block) *State {
|
|||
Blocks: root.Build(),
|
||||
},
|
||||
}).(*State)
|
||||
ApplyState(st, true)
|
||||
ApplyState("", st, true)
|
||||
return st.NewState()
|
||||
}
|
||||
|
||||
|
@ -879,7 +880,7 @@ func TestRootDeviceChanges(t *testing.T) {
|
|||
s := a.NewState()
|
||||
|
||||
// when
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
|
@ -897,7 +898,7 @@ func TestRootDeviceChanges(t *testing.T) {
|
|||
s.AddDevice(device)
|
||||
|
||||
// when
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
|
@ -916,7 +917,7 @@ func TestRootDeviceChanges(t *testing.T) {
|
|||
s := a.NewState()
|
||||
s.SetDeviceName("id", "test1")
|
||||
// when
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
|
@ -935,7 +936,7 @@ func TestRootDeviceChanges(t *testing.T) {
|
|||
s.AddDevice(device)
|
||||
s.parent = nil
|
||||
// when
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
|
@ -980,7 +981,7 @@ func TestTableChanges(t *testing.T) {
|
|||
},
|
||||
}}))
|
||||
|
||||
msgs, _, err := ApplyState(s, true)
|
||||
msgs, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 1)
|
||||
|
||||
|
@ -988,7 +989,7 @@ func TestTableChanges(t *testing.T) {
|
|||
rows := s.Get("tableRow1")
|
||||
require.NotNil(t, rows)
|
||||
rows.Model().GetTableRow().IsHeader = true
|
||||
msgs, _, err = ApplyState(s, true)
|
||||
msgs, _, err = ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 1)
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/base"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/bookmark"
|
||||
|
@ -17,6 +15,8 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/simple/table"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/text"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/widget"
|
||||
"github.com/anyproto/anytype-heart/core/event"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
|
@ -314,13 +314,13 @@ func WrapEventMessages(virtual bool, msgs []*pb.EventMessage) []simple.EventMess
|
|||
return wmsgs
|
||||
}
|
||||
|
||||
func StructDiffIntoEvents(contextId string, diff *types.Struct) (msgs []*pb.EventMessage) {
|
||||
return StructDiffIntoEventsWithSubIds(contextId, diff, nil, nil)
|
||||
func StructDiffIntoEvents(spaceId string, contextId string, diff *domain.Details) (msgs []*pb.EventMessage) {
|
||||
return StructDiffIntoEventsWithSubIds(spaceId, contextId, diff, nil, nil)
|
||||
}
|
||||
|
||||
// StructDiffIntoEvents converts map into events. nil map value converts to Remove event
|
||||
func StructDiffIntoEventsWithSubIds(contextId string, diff *types.Struct, keys []string, subIds []string) (msgs []*pb.EventMessage) {
|
||||
if diff == nil || len(diff.Fields) == 0 {
|
||||
func StructDiffIntoEventsWithSubIds(spaceId string, contextId string, diff *domain.Details, keys []domain.RelationKey, subIds []string) (msgs []*pb.EventMessage) {
|
||||
if diff.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
|
@ -328,39 +328,37 @@ func StructDiffIntoEventsWithSubIds(contextId string, diff *types.Struct, keys [
|
|||
details []*pb.EventObjectDetailsAmendKeyValue
|
||||
)
|
||||
|
||||
for k, v := range diff.Fields {
|
||||
for k, v := range diff.Iterate() {
|
||||
key := string(k)
|
||||
if len(keys) > 0 && slice.FindPos(keys, k) == -1 {
|
||||
continue
|
||||
}
|
||||
if v == nil {
|
||||
removed = append(removed, k)
|
||||
// TODO This is not correct! Rewrite this code to use separate diff structures
|
||||
if v.IsNull() {
|
||||
removed = append(removed, key)
|
||||
continue
|
||||
}
|
||||
details = append(details, &pb.EventObjectDetailsAmendKeyValue{Key: k, Value: v})
|
||||
}
|
||||
if len(details) > 0 {
|
||||
msgs = append(msgs, &pb.EventMessage{
|
||||
Value: &pb.EventMessageValueOfObjectDetailsAmend{
|
||||
ObjectDetailsAmend: &pb.EventObjectDetailsAmend{
|
||||
Id: contextId,
|
||||
Details: details,
|
||||
SubIds: subIds,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
if len(removed) > 0 {
|
||||
msgs = append(msgs, &pb.EventMessage{
|
||||
Value: &pb.EventMessageValueOfObjectDetailsUnset{
|
||||
ObjectDetailsUnset: &pb.EventObjectDetailsUnset{
|
||||
Id: contextId,
|
||||
Keys: removed,
|
||||
SubIds: subIds,
|
||||
},
|
||||
},
|
||||
})
|
||||
details = append(details, &pb.EventObjectDetailsAmendKeyValue{Key: key, Value: v.ToProto()})
|
||||
}
|
||||
|
||||
if len(details) > 0 {
|
||||
msgs = append(msgs, event.NewMessage(spaceId, &pb.EventMessageValueOfObjectDetailsAmend{
|
||||
ObjectDetailsAmend: &pb.EventObjectDetailsAmend{
|
||||
Id: contextId,
|
||||
Details: details,
|
||||
SubIds: subIds,
|
||||
},
|
||||
}))
|
||||
}
|
||||
if len(removed) > 0 {
|
||||
msgs = append(msgs, event.NewMessage(spaceId, &pb.EventMessageValueOfObjectDetailsUnset{
|
||||
ObjectDetailsUnset: &pb.EventObjectDetailsUnset{
|
||||
Id: contextId,
|
||||
Keys: removed,
|
||||
SubIds: subIds,
|
||||
},
|
||||
}))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
r := NewDoc("1", nil)
|
||||
r.(*State).Add(simple.New(&model.Block{Id: "1"}))
|
||||
s := r.NewState()
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 0)
|
||||
assert.Empty(t, hist)
|
||||
|
@ -63,7 +63,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
}).(*State)
|
||||
s := r.NewState()
|
||||
s.Get("one")
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 1)
|
||||
assert.Len(t, hist.Change, 1)
|
||||
|
@ -97,7 +97,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
s.Get("tableRows")
|
||||
s.Get("tableColumns")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2) // 1 remove + 1 change
|
||||
assert.Len(t, hist.Change, 1)
|
||||
|
@ -122,7 +122,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
s := r.NewState()
|
||||
s.Get("c1")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2) // 1 remove + 1 change
|
||||
assert.Len(t, hist.Change, 1)
|
||||
|
@ -146,7 +146,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
s := r.NewState()
|
||||
s.Unlink("c2")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 4) // 1 row change + 1 remove + 2 width reset
|
||||
assert.Len(t, hist.Remove, 2)
|
||||
|
@ -168,7 +168,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
|
||||
s := r.NewState()
|
||||
s.normalizeTree()
|
||||
ApplyState(s, true)
|
||||
ApplyState("", s, true)
|
||||
blocks := r.Blocks()
|
||||
result := []string{}
|
||||
divs := []string{}
|
||||
|
@ -207,7 +207,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
r.Add(simple.New(&model.Block{Id: "root", ChildrenIds: rootIds}))
|
||||
|
||||
s := r.NewState()
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
|
@ -221,7 +221,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
id := fmt.Sprint(i)
|
||||
s.Add(simple.New(&model.Block{Id: id}))
|
||||
s.InsertTo(targetId, targetPos, id)
|
||||
msgs, _, err := ApplyState(s, true)
|
||||
msgs, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
for _, msg := range msgs {
|
||||
if add := msg.Msg.GetBlockAdd(); add != nil {
|
||||
|
@ -262,7 +262,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
for _, b := range ev.Blocks {
|
||||
r.Add(simple.New(b))
|
||||
}
|
||||
_, _, err = ApplyState(r.NewState(), true)
|
||||
_, _, err = ApplyState("", r.NewState(), true)
|
||||
require.NoError(t, err)
|
||||
// t.Log(r.String())
|
||||
|
||||
|
@ -283,7 +283,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
r.Add(simple.New(&model.Block{Id: "e"}))
|
||||
s := r.NewState()
|
||||
require.NoError(t, s.Normalize(false))
|
||||
_, _, err := ApplyState(s, false)
|
||||
_, _, err := ApplyState("", s, false)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{"a", "b", "c"}, r.Pick("root").Model().ChildrenIds)
|
||||
assert.Equal(t, []string{"d"}, r.Pick("a").Model().ChildrenIds)
|
||||
|
@ -305,7 +305,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
|
||||
s := r.NewState()
|
||||
s.normalizeTree()
|
||||
ApplyState(s, true)
|
||||
ApplyState("", s, true)
|
||||
assert.Equal(t, "header", s.Pick(s.RootId()).Model().ChildrenIds[0])
|
||||
})
|
||||
|
||||
|
@ -336,7 +336,7 @@ func TestState_Normalize(t *testing.T) {
|
|||
|
||||
// when
|
||||
require.NoError(t, s.Normalize(false))
|
||||
_, msg, err := ApplyState(s, false)
|
||||
_, msg, err := ApplyState("", s, false)
|
||||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
|
@ -463,7 +463,7 @@ func BenchmarkNormalize(b *testing.B) {
|
|||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
ApplyState(r.NewState(), true)
|
||||
ApplyState("", r.NewState(), true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "second"}))
|
||||
s.InsertTo("", 0, "first", "second")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2)
|
||||
assert.Len(t, hist.Add, 2)
|
||||
|
@ -42,7 +42,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "second"}))
|
||||
s.InsertTo("target", model.Block_Bottom, "first", "second")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2)
|
||||
assert.Len(t, hist.Add, 2)
|
||||
|
@ -59,7 +59,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "second"}))
|
||||
s.InsertTo("target", model.Block_Top, "first", "second")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2)
|
||||
assert.Len(t, hist.Add, 2)
|
||||
|
@ -76,7 +76,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "second"}))
|
||||
s.InsertTo("target", model.Block_Inner, "first", "second")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2)
|
||||
assert.Len(t, hist.Add, 2)
|
||||
|
@ -95,7 +95,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "second"}))
|
||||
s.InsertTo("target", model.Block_Replace, "first", "second")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 3)
|
||||
assert.Len(t, hist.Remove, 1)
|
||||
|
@ -106,7 +106,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
|
||||
s = r.NewState()
|
||||
require.NoError(t, r.InsertTo("first", model.Block_Replace, "child"))
|
||||
_, _, err = ApplyState(s, true)
|
||||
_, _, err = ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{"child", "second"}, r.Pick("root").Model().ChildrenIds)
|
||||
})
|
||||
|
@ -123,7 +123,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
|
||||
// when
|
||||
err := s.InsertTo("target", model.Block_Replace, "link")
|
||||
_, _, err2 := ApplyState(s, true)
|
||||
_, _, err2 := ApplyState("", s, true)
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
|
@ -142,7 +142,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
|
||||
// when
|
||||
err := s.InsertTo("target", model.Block_Replace, "link")
|
||||
_, _, err2 := ApplyState(s, true)
|
||||
_, _, err2 := ApplyState("", s, true)
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
|
@ -174,7 +174,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "second"}))
|
||||
s.InsertTo("target", pos, "first", "second")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, msgs)
|
||||
assert.Len(t, hist.Remove, 0)
|
||||
|
@ -207,7 +207,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "third"}))
|
||||
s.InsertTo(c1.Model().Id, model.Block_Left, "third")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2)
|
||||
assert.Len(t, hist.Remove, 0)
|
||||
|
@ -220,7 +220,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "third"}))
|
||||
s.InsertTo(c2.Model().Id, model.Block_Left, "third")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2)
|
||||
assert.Len(t, hist.Remove, 0)
|
||||
|
@ -233,7 +233,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "third"}))
|
||||
s.InsertTo(c2.Model().Id, model.Block_Right, "third")
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2)
|
||||
assert.Len(t, hist.Remove, 0)
|
||||
|
@ -250,7 +250,7 @@ func TestState_InsertTo(t *testing.T) {
|
|||
s.Add(simple.New(&model.Block{Id: "2", ChildrenIds: []string{"1"}}))
|
||||
s.Get("root").Model().ChildrenIds = []string{"1"}
|
||||
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
|
|
|
@ -7,11 +7,14 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/anyproto/any-store/anyenc"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/block/undo"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/event"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
|
@ -49,9 +52,9 @@ type Doc interface {
|
|||
NewStateCtx(ctx session.Context) *State
|
||||
Blocks() []*model.Block
|
||||
Pick(id string) (b simple.Block)
|
||||
Details() *types.Struct
|
||||
CombinedDetails() *types.Struct
|
||||
LocalDetails() *types.Struct
|
||||
Details() *domain.Details
|
||||
CombinedDetails() *domain.Details
|
||||
LocalDetails() *domain.Details
|
||||
|
||||
GetRelationLinks() pbtypes.RelationLinks
|
||||
|
||||
|
@ -113,8 +116,8 @@ type State struct {
|
|||
changes []*pb.ChangeContent
|
||||
fileInfo FileInfo
|
||||
fileKeys []pb.ChangeFileKeys // Deprecated
|
||||
details *types.Struct
|
||||
localDetails *types.Struct
|
||||
details *domain.Details
|
||||
localDetails *domain.Details
|
||||
relationLinks pbtypes.RelationLinks
|
||||
notifications map[string]*model.Notification
|
||||
deviceStore map[string]*model.DeviceInfo
|
||||
|
@ -194,7 +197,7 @@ func (s *State) GroupId() string {
|
|||
}
|
||||
|
||||
func (s *State) SpaceID() string {
|
||||
return pbtypes.GetString(s.LocalDetails(), bundle.RelationKeySpaceId.String())
|
||||
return s.LocalDetails().GetString(bundle.RelationKeySpaceId)
|
||||
}
|
||||
|
||||
func (s *State) Add(b simple.Block) (ok bool) {
|
||||
|
@ -411,25 +414,25 @@ func (s *State) SearchText() string {
|
|||
return builder.String()
|
||||
}
|
||||
|
||||
func ApplyState(s *State, withLayouts bool) (msgs []simple.EventMessage, action undo.Action, err error) {
|
||||
return s.apply(false, false, withLayouts)
|
||||
func ApplyState(spaceId string, s *State, withLayouts bool) (msgs []simple.EventMessage, action undo.Action, err error) {
|
||||
return s.apply(spaceId, false, false, withLayouts)
|
||||
}
|
||||
|
||||
func ApplyStateFast(s *State) (msgs []simple.EventMessage, action undo.Action, err error) {
|
||||
return s.apply(true, false, false)
|
||||
func ApplyStateFast(spaceId string, s *State) (msgs []simple.EventMessage, action undo.Action, err error) {
|
||||
return s.apply(spaceId, true, false, false)
|
||||
}
|
||||
|
||||
func ApplyStateFastOne(s *State) (msgs []simple.EventMessage, action undo.Action, err error) {
|
||||
return s.apply(true, true, false)
|
||||
func ApplyStateFastOne(spaceId string, s *State) (msgs []simple.EventMessage, action undo.Action, err error) {
|
||||
return s.apply(spaceId, true, true, false)
|
||||
}
|
||||
|
||||
func (s *State) apply(fast, one, withLayouts bool) (msgs []simple.EventMessage, action undo.Action, err error) {
|
||||
func (s *State) apply(spaceId string, fast, one, withLayouts bool) (msgs []simple.EventMessage, action undo.Action, err error) {
|
||||
if s.parent != nil && (s.parent.parent != nil || fast) {
|
||||
s.intermediateApply()
|
||||
if one {
|
||||
return
|
||||
}
|
||||
return s.parent.apply(fast, one, withLayouts)
|
||||
return s.parent.apply("", fast, one, withLayouts)
|
||||
}
|
||||
if fast {
|
||||
return
|
||||
|
@ -452,7 +455,7 @@ func (s *State) apply(fast, one, withLayouts bool) (msgs []simple.EventMessage,
|
|||
|
||||
// apply snippet
|
||||
if s.Snippet() != s.parent.Snippet() {
|
||||
s.SetLocalDetail(bundle.RelationKeySnippet.String(), pbtypes.String(s.Snippet()))
|
||||
s.SetLocalDetail(bundle.RelationKeySnippet, domain.String(s.Snippet()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,13 +488,13 @@ func (s *State) apply(fast, one, withLayouts bool) (msgs []simple.EventMessage,
|
|||
}
|
||||
flushNewBlocks := func() {
|
||||
if len(newBlocks) > 0 {
|
||||
msgs = append(msgs, simple.EventMessage{Msg: &pb.EventMessage{
|
||||
Value: &pb.EventMessageValueOfBlockAdd{
|
||||
msgs = append(msgs, simple.EventMessage{Msg: event.NewMessage(spaceId,
|
||||
&pb.EventMessageValueOfBlockAdd{
|
||||
BlockAdd: &pb.EventBlockAdd{
|
||||
Blocks: newBlocks,
|
||||
},
|
||||
},
|
||||
}})
|
||||
}),
|
||||
})
|
||||
}
|
||||
newBlocks = nil
|
||||
}
|
||||
|
@ -515,7 +518,7 @@ func (s *State) apply(fast, one, withLayouts bool) (msgs []simple.EventMessage,
|
|||
db.DetailsInit(s)
|
||||
}
|
||||
}
|
||||
diff, err := orig.Diff(b)
|
||||
diff, err := orig.Diff(spaceId, b)
|
||||
if err != nil {
|
||||
return nil, undo.Action{}, err
|
||||
}
|
||||
|
@ -551,11 +554,9 @@ func (s *State) apply(fast, one, withLayouts bool) (msgs []simple.EventMessage,
|
|||
}
|
||||
}
|
||||
if len(toRemove) > 0 {
|
||||
msgs = append(msgs, simple.EventMessage{Msg: &pb.EventMessage{
|
||||
Value: &pb.EventMessageValueOfBlockDelete{
|
||||
BlockDelete: &pb.EventBlockDelete{BlockIds: toRemove},
|
||||
},
|
||||
}})
|
||||
msgs = append(msgs, simple.EventMessage{Msg: event.NewMessage(s.SpaceID(), &pb.EventMessageValueOfBlockDelete{
|
||||
BlockDelete: &pb.EventBlockDelete{BlockIds: toRemove},
|
||||
})})
|
||||
}
|
||||
|
||||
if s.parent != nil && s.relationLinks != nil {
|
||||
|
@ -570,26 +571,24 @@ func (s *State) apply(fast, one, withLayouts bool) (msgs []simple.EventMessage,
|
|||
|
||||
if len(removed) > 0 {
|
||||
msgs = append(msgs, WrapEventMessages(false, []*pb.EventMessage{
|
||||
{
|
||||
Value: &pb.EventMessageValueOfObjectRelationsRemove{
|
||||
ObjectRelationsRemove: &pb.EventObjectRelationsRemove{
|
||||
Id: s.RootId(),
|
||||
RelationKeys: removed,
|
||||
},
|
||||
event.NewMessage(s.SpaceID(), &pb.EventMessageValueOfObjectRelationsRemove{
|
||||
ObjectRelationsRemove: &pb.EventObjectRelationsRemove{
|
||||
Id: s.RootId(),
|
||||
RelationKeys: removed,
|
||||
},
|
||||
},
|
||||
),
|
||||
})...)
|
||||
}
|
||||
if len(added) > 0 {
|
||||
msgs = append(msgs, WrapEventMessages(false, []*pb.EventMessage{
|
||||
{
|
||||
Value: &pb.EventMessageValueOfObjectRelationsAmend{
|
||||
ObjectRelationsAmend: &pb.EventObjectRelationsAmend{
|
||||
Id: s.RootId(),
|
||||
RelationLinks: added,
|
||||
},
|
||||
event.NewMessage(s.SpaceID(), &pb.EventMessageValueOfObjectRelationsAmend{
|
||||
ObjectRelationsAmend: &pb.EventObjectRelationsAmend{
|
||||
Id: s.RootId(),
|
||||
RelationLinks: added,
|
||||
},
|
||||
},
|
||||
),
|
||||
})...)
|
||||
}
|
||||
}
|
||||
|
@ -621,9 +620,9 @@ func (s *State) apply(fast, one, withLayouts bool) (msgs []simple.EventMessage,
|
|||
}
|
||||
if s.parent != nil && s.details != nil {
|
||||
prev := s.parent.Details()
|
||||
if diff := pbtypes.StructDiff(prev, s.details); diff != nil {
|
||||
action.Details = &undo.Details{Before: pbtypes.CopyStruct(prev, false), After: pbtypes.CopyStruct(s.details, false)}
|
||||
msgs = append(msgs, WrapEventMessages(false, StructDiffIntoEvents(s.RootId(), diff))...)
|
||||
if diff := domain.StructDiff(prev, s.details); diff != nil {
|
||||
action.Details = &undo.Details{Before: prev.Copy(), After: s.details.Copy()}
|
||||
msgs = append(msgs, WrapEventMessages(false, StructDiffIntoEvents(s.SpaceID(), s.RootId(), diff))...)
|
||||
s.parent.details = s.details
|
||||
} else if !s.details.Equal(s.parent.details) {
|
||||
s.parent.details = s.details
|
||||
|
@ -652,8 +651,8 @@ func (s *State) apply(fast, one, withLayouts bool) (msgs []simple.EventMessage,
|
|||
|
||||
if s.parent != nil && s.localDetails != nil {
|
||||
prev := s.parent.LocalDetails()
|
||||
if diff := pbtypes.StructDiff(prev, s.localDetails); diff != nil {
|
||||
msgs = append(msgs, WrapEventMessages(true, StructDiffIntoEvents(s.RootId(), diff))...)
|
||||
if diff := domain.StructDiff(prev, s.localDetails); diff != nil {
|
||||
msgs = append(msgs, WrapEventMessages(true, StructDiffIntoEvents(spaceId, s.RootId(), diff))...)
|
||||
s.parent.localDetails = s.localDetails
|
||||
} else if !s.localDetails.Equal(s.parent.localDetails) {
|
||||
s.parent.localDetails = s.localDetails
|
||||
|
@ -818,13 +817,16 @@ func (s *State) StringDebug() string {
|
|||
}
|
||||
|
||||
fmt.Fprintf(buf, "\nDetails:\n")
|
||||
pbtypes.SortedRange(s.Details(), func(k string, v *types.Value) {
|
||||
fmt.Fprintf(buf, "\t%s:\t%v\n", k, pbtypes.Sprint(v))
|
||||
})
|
||||
arena := &anyenc.Arena{}
|
||||
for k, v := range s.Details().IterateSorted() {
|
||||
raw := string(v.ToAnyEnc(arena).MarshalTo(nil))
|
||||
fmt.Fprintf(buf, "\t%s:\t%v\n", k, raw)
|
||||
}
|
||||
fmt.Fprintf(buf, "\nLocal details:\n")
|
||||
pbtypes.SortedRange(s.LocalDetails(), func(k string, v *types.Value) {
|
||||
fmt.Fprintf(buf, "\t%s:\t%v\n", k, pbtypes.Sprint(v))
|
||||
})
|
||||
for k, v := range s.LocalDetails().IterateSorted() {
|
||||
raw := string(v.ToAnyEnc(arena).MarshalTo(nil))
|
||||
fmt.Fprintf(buf, "\t%s:\t%v\n", k, raw)
|
||||
}
|
||||
fmt.Fprintf(buf, "\nBlocks:\n")
|
||||
s.writeString(buf, 0, s.RootId())
|
||||
fmt.Fprintf(buf, "\nCollection:\n")
|
||||
|
@ -839,17 +841,18 @@ func (s *State) StringDebug() string {
|
|||
return buf.String()
|
||||
}
|
||||
|
||||
func (s *State) SetDetails(d *types.Struct) *State {
|
||||
func (s *State) SetDetails(d *domain.Details) *State {
|
||||
// TODO: GO-2062 Need to refactor details shortening, as it could cut string incorrectly
|
||||
// if d != nil && d.Fields != nil {
|
||||
// shortenDetailsToLimit(s.rootId, d.Fields)
|
||||
// }
|
||||
local := pbtypes.StructFilterKeys(d, bundle.LocalAndDerivedRelationKeys)
|
||||
if local != nil && local.GetFields() != nil && len(local.GetFields()) > 0 {
|
||||
for k, v := range local.Fields {
|
||||
|
||||
local := d.CopyOnlyKeys(bundle.LocalAndDerivedRelationKeys...)
|
||||
if local != nil && local.Len() > 0 {
|
||||
for k, v := range local.Iterate() {
|
||||
s.SetLocalDetail(k, v)
|
||||
}
|
||||
s.details = pbtypes.StructCutKeys(d, bundle.LocalAndDerivedRelationKeys)
|
||||
s.details = d.CopyWithoutKeys(bundle.LocalAndDerivedRelationKeys...)
|
||||
return s
|
||||
}
|
||||
s.details = d
|
||||
|
@ -857,56 +860,41 @@ func (s *State) SetDetails(d *types.Struct) *State {
|
|||
}
|
||||
|
||||
// SetDetailAndBundledRelation sets the detail value and bundled relation in case it is missing
|
||||
func (s *State) SetDetailAndBundledRelation(key domain.RelationKey, value *types.Value) {
|
||||
func (s *State) SetDetailAndBundledRelation(key domain.RelationKey, value domain.Value) {
|
||||
s.AddBundledRelationLinks(key)
|
||||
s.SetDetail(key.String(), value)
|
||||
s.SetDetail(key, value)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *State) SetLocalDetail(key string, value *types.Value) {
|
||||
func (s *State) SetLocalDetail(key domain.RelationKey, value domain.Value) {
|
||||
if s.localDetails == nil && s.parent != nil {
|
||||
d := s.parent.Details()
|
||||
if d.GetFields() != nil {
|
||||
if d != nil {
|
||||
// optimisation so we don't need to copy the struct if nothing has changed
|
||||
if prev, exists := d.Fields[key]; exists && prev.Equal(value) {
|
||||
if prev := d.Get(key); prev.Ok() && prev.Equal(value) {
|
||||
return
|
||||
}
|
||||
}
|
||||
s.localDetails = pbtypes.CopyStruct(s.parent.LocalDetails(), false)
|
||||
s.localDetails = s.parent.LocalDetails().Copy()
|
||||
}
|
||||
if s.localDetails == nil || s.localDetails.Fields == nil {
|
||||
s.localDetails = &types.Struct{Fields: map[string]*types.Value{}}
|
||||
if s.localDetails == nil {
|
||||
s.localDetails = domain.NewDetails()
|
||||
}
|
||||
|
||||
if value == nil {
|
||||
delete(s.localDetails.Fields, key)
|
||||
return
|
||||
}
|
||||
|
||||
if err := pbtypes.ValidateValue(value); err != nil {
|
||||
log.Errorf("invalid value for pb %s: %v", key, err)
|
||||
}
|
||||
|
||||
s.localDetails.Fields[key] = value
|
||||
s.localDetails.Set(key, value)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *State) SetLocalDetails(d *types.Struct) {
|
||||
for k, v := range d.GetFields() {
|
||||
if v == nil {
|
||||
delete(d.Fields, k)
|
||||
}
|
||||
}
|
||||
func (s *State) SetLocalDetails(d *domain.Details) {
|
||||
s.localDetails = d
|
||||
}
|
||||
|
||||
func (s *State) AddDetails(details *types.Struct) {
|
||||
for k, v := range details.GetFields() {
|
||||
func (s *State) AddDetails(details *domain.Details) {
|
||||
for k, v := range details.Iterate() {
|
||||
s.SetDetail(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) SetDetail(key string, value *types.Value) {
|
||||
func (s *State) SetDetail(key domain.RelationKey, value domain.Value) {
|
||||
// TODO: GO-2062 Need to refactor details shortening, as it could cut string incorrectly
|
||||
// value = shortenValueToLimit(s.rootId, key, value)
|
||||
|
||||
|
@ -917,34 +905,24 @@ func (s *State) SetDetail(key string, value *types.Value) {
|
|||
|
||||
if s.details == nil && s.parent != nil {
|
||||
d := s.parent.Details()
|
||||
if d.GetFields() != nil {
|
||||
if d != nil {
|
||||
// optimisation so we don't need to copy the struct if nothing has changed
|
||||
if prev, exists := d.Fields[key]; exists && prev.Equal(value) {
|
||||
if prev := d.Get(key); prev.Ok() && prev.Equal(value) {
|
||||
return
|
||||
}
|
||||
s.details = d.Copy()
|
||||
}
|
||||
s.details = pbtypes.CopyStruct(d, false)
|
||||
}
|
||||
if s.details == nil || s.details.Fields == nil {
|
||||
s.details = &types.Struct{Fields: map[string]*types.Value{}}
|
||||
if s.details == nil {
|
||||
s.details = domain.NewDetails()
|
||||
}
|
||||
|
||||
if value == nil {
|
||||
delete(s.details.Fields, key)
|
||||
return
|
||||
}
|
||||
|
||||
if err := pbtypes.ValidateValue(value); err != nil {
|
||||
log.Errorf("invalid value for pb %s: %v", key, err)
|
||||
}
|
||||
|
||||
s.details.Fields[key] = value
|
||||
s.details.Set(key, value)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *State) SetAlign(align model.BlockAlign, ids ...string) (err error) {
|
||||
if len(ids) == 0 {
|
||||
s.SetDetail(bundle.RelationKeyLayoutAlign.String(), pbtypes.Int64(int64(align)))
|
||||
s.SetDetail(bundle.RelationKeyLayoutAlign, domain.Int64(align))
|
||||
ids = []string{TitleBlockID, DescriptionBlockID, FeaturedRelationsID}
|
||||
}
|
||||
for _, id := range ids {
|
||||
|
@ -998,19 +976,13 @@ func (s *State) SetObjectTypeKeys(objectTypeKeys []domain.TypeKey) *State {
|
|||
return s
|
||||
}
|
||||
|
||||
func (s *State) InjectLocalDetails(localDetails *types.Struct) {
|
||||
for key, v := range localDetails.GetFields() {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
if _, isNull := v.Kind.(*types.Value_NullValue); isNull {
|
||||
continue
|
||||
}
|
||||
s.SetDetailAndBundledRelation(domain.RelationKey(key), v)
|
||||
func (s *State) InjectLocalDetails(localDetails *domain.Details) {
|
||||
for k, v := range localDetails.Iterate() {
|
||||
s.SetDetailAndBundledRelation(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) LocalDetails() *types.Struct {
|
||||
func (s *State) LocalDetails() *domain.Details {
|
||||
if s.localDetails == nil && s.parent != nil {
|
||||
return s.parent.LocalDetails()
|
||||
}
|
||||
|
@ -1018,21 +990,12 @@ func (s *State) LocalDetails() *types.Struct {
|
|||
return s.localDetails
|
||||
}
|
||||
|
||||
func (s *State) CombinedDetails() *types.Struct {
|
||||
return pbtypes.StructMerge(s.Details(), s.LocalDetails(), false)
|
||||
func (s *State) CombinedDetails() *domain.Details {
|
||||
// TODO Implement combined details struct with two underlying details
|
||||
return s.Details().Merge(s.LocalDetails())
|
||||
}
|
||||
|
||||
func (s *State) HasCombinedDetailsKey(key string) bool {
|
||||
if pbtypes.HasField(s.Details(), key) {
|
||||
return true
|
||||
}
|
||||
if pbtypes.HasField(s.LocalDetails(), key) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *State) Details() *types.Struct {
|
||||
func (s *State) Details() *domain.Details {
|
||||
if s.details == nil && s.parent != nil {
|
||||
return s.parent.Details()
|
||||
}
|
||||
|
@ -1055,7 +1018,7 @@ func (s *State) ObjectTypeKey() domain.TypeKey {
|
|||
if len(objTypes) == 0 && !s.noObjectType {
|
||||
log.Debugf("object %s (%s) has %d object types instead of 1",
|
||||
s.RootId(),
|
||||
pbtypes.GetString(s.Details(), bundle.RelationKeyName.String()),
|
||||
s.Details().GetString(bundle.RelationKeyName),
|
||||
len(objTypes),
|
||||
)
|
||||
}
|
||||
|
@ -1091,19 +1054,20 @@ func (s *State) Snippet() string {
|
|||
return textutil.TruncateEllipsized(builder.String(), snippetMaxSize)
|
||||
}
|
||||
|
||||
func (s *State) FileRelationKeys() []string {
|
||||
var keys []string
|
||||
func (s *State) FileRelationKeys() []domain.RelationKey {
|
||||
var keys []domain.RelationKey
|
||||
for _, rel := range s.GetRelationLinks() {
|
||||
// coverId can contain both hash or predefined cover id
|
||||
if rel.Format == model.RelationFormat_file {
|
||||
if slice.FindPos(keys, rel.Key) == -1 {
|
||||
keys = append(keys, rel.Key)
|
||||
key := domain.RelationKey(rel.Key)
|
||||
if slice.FindPos(keys, key) == -1 {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
}
|
||||
if rel.Key == bundle.RelationKeyCoverId.String() {
|
||||
coverType := pbtypes.GetInt64(s.Details(), bundle.RelationKeyCoverType.String())
|
||||
if (coverType == 1 || coverType == 4) && slice.FindPos(keys, rel.Key) == -1 {
|
||||
keys = append(keys, rel.Key)
|
||||
coverType := s.Details().GetInt64(bundle.RelationKeyCoverType)
|
||||
if (coverType == 1 || coverType == 4) && slice.FindPos(keys, domain.RelationKey(rel.Key)) == -1 {
|
||||
keys = append(keys, domain.RelationKey(rel.Key))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1132,11 +1096,20 @@ func (s *State) IterateLinkedFilesInDetails(proc func(id string)) {
|
|||
// Detail is saved only if at least one id is changed
|
||||
func (s *State) ModifyLinkedFilesInDetails(modifier func(id string) string) {
|
||||
details := s.Details()
|
||||
if details == nil || details.Fields == nil {
|
||||
if details == nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, key := range s.FileRelationKeys() {
|
||||
if key == bundle.RelationKeyCoverId {
|
||||
v := details.GetString(bundle.RelationKeyCoverId)
|
||||
_, err := cid.Decode(v)
|
||||
if err != nil {
|
||||
// this is an exception cause coverId can contain not a file hash but color
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
s.modifyIdsInDetail(details, key, modifier)
|
||||
}
|
||||
}
|
||||
|
@ -1145,18 +1118,19 @@ func (s *State) ModifyLinkedFilesInDetails(modifier func(id string) string) {
|
|||
// Detail is saved only if at least one id is changed
|
||||
func (s *State) ModifyLinkedObjectsInDetails(modifier func(id string) string) {
|
||||
details := s.Details()
|
||||
if details == nil || details.Fields == nil {
|
||||
if details == nil {
|
||||
return
|
||||
}
|
||||
for _, rel := range s.GetRelationLinks() {
|
||||
if rel.Format == model.RelationFormat_object {
|
||||
s.modifyIdsInDetail(details, rel.Key, modifier)
|
||||
s.modifyIdsInDetail(details, domain.RelationKey(rel.Key), modifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) modifyIdsInDetail(details *types.Struct, key string, modifier func(id string) string) {
|
||||
if ids := pbtypes.GetStringList(details, key); len(ids) > 0 {
|
||||
func (s *State) modifyIdsInDetail(details *domain.Details, key domain.RelationKey, modifier func(id string) string) {
|
||||
// TODO TryStringList in pbtypes return []string{singleValue} for string values
|
||||
if ids := details.GetStringList(key); len(ids) > 0 {
|
||||
var anyChanges bool
|
||||
for i, oldId := range ids {
|
||||
if oldId == "" {
|
||||
|
@ -1169,11 +1143,11 @@ func (s *State) modifyIdsInDetail(details *types.Struct, key string, modifier fu
|
|||
}
|
||||
}
|
||||
if anyChanges {
|
||||
switch details.Fields[key].Kind.(type) {
|
||||
case *types.Value_StringValue:
|
||||
s.SetDetail(key, pbtypes.String(ids[0]))
|
||||
case *types.Value_ListValue:
|
||||
s.SetDetail(key, pbtypes.StringList(ids))
|
||||
v := details.Get(key)
|
||||
if _, ok := v.TryString(); ok {
|
||||
s.SetDetail(key, domain.String(ids[0]))
|
||||
} else if _, ok := v.TryStringList(); ok {
|
||||
s.SetDetail(key, domain.StringList(ids))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1211,7 +1185,8 @@ func (s *State) CheckRestrictions() (err error) {
|
|||
}
|
||||
if rest.Edit {
|
||||
if ob := s.parent.Pick(id); ob != nil {
|
||||
if msgs, _ := ob.Diff(b); len(msgs) > 0 {
|
||||
// SpaceId is empty because only the fact that there is any diff matters here
|
||||
if msgs, _ := ob.Diff("", b); len(msgs) > 0 {
|
||||
return ErrRestricted
|
||||
}
|
||||
}
|
||||
|
@ -1253,7 +1228,7 @@ func (s *State) Validate() (err error) {
|
|||
|
||||
// IsEmpty returns whether state has any blocks beside template blocks(root, header, title, etc)
|
||||
func (s *State) IsEmpty(checkTitle bool) bool {
|
||||
if checkTitle && pbtypes.GetString(s.Details(), bundle.RelationKeyName.String()) != "" {
|
||||
if checkTitle && s.Details().GetString(bundle.RelationKeyName) != "" {
|
||||
return false
|
||||
}
|
||||
var emptyTextFound bool
|
||||
|
@ -1267,7 +1242,7 @@ func (s *State) IsEmpty(checkTitle bool) bool {
|
|||
emptyTextFound = true
|
||||
}
|
||||
|
||||
if pbtypes.GetString(s.Details(), bundle.RelationKeyDescription.String()) != "" {
|
||||
if s.Details().GetString(bundle.RelationKeyDescription) != "" {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -1311,8 +1286,8 @@ func (s *State) Copy() *State {
|
|||
ctx: s.ctx,
|
||||
blocks: blocks,
|
||||
rootId: s.rootId,
|
||||
details: pbtypes.CopyStruct(s.Details(), false),
|
||||
localDetails: pbtypes.CopyStruct(s.LocalDetails(), false),
|
||||
details: s.Details().Copy(),
|
||||
localDetails: s.LocalDetails().Copy(),
|
||||
relationLinks: s.GetRelationLinks(), // Get methods copy inside
|
||||
objectTypeKeys: objTypes,
|
||||
noObjectType: s.noObjectType,
|
||||
|
@ -1375,12 +1350,13 @@ func (s *State) IsTheHeaderChange() bool {
|
|||
return s.changeId == s.rootId || s.changeId == "" && s.parent == nil
|
||||
}
|
||||
|
||||
func (s *State) RemoveDetail(keys ...string) (ok bool) {
|
||||
det := pbtypes.CopyStruct(s.Details(), false)
|
||||
if det != nil && det.Fields != nil {
|
||||
func (s *State) RemoveDetail(keys ...domain.RelationKey) (ok bool) {
|
||||
// TODO It could be lazily copied only if actual deletion is happened
|
||||
det := s.Details().Copy()
|
||||
if det != nil {
|
||||
for _, key := range keys {
|
||||
if _, ex := det.Fields[key]; ex {
|
||||
delete(det.Fields, key)
|
||||
if det.Has(key) {
|
||||
det.Delete(key)
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
|
@ -1391,12 +1367,13 @@ func (s *State) RemoveDetail(keys ...string) (ok bool) {
|
|||
return s.RemoveLocalDetail(keys...) || ok
|
||||
}
|
||||
|
||||
func (s *State) RemoveLocalDetail(keys ...string) (ok bool) {
|
||||
det := pbtypes.CopyStruct(s.LocalDetails(), false)
|
||||
if det != nil && det.Fields != nil {
|
||||
func (s *State) RemoveLocalDetail(keys ...domain.RelationKey) (ok bool) {
|
||||
// TODO It could be lazily copied only if actual deletion is happened
|
||||
det := s.LocalDetails().Copy()
|
||||
if det != nil {
|
||||
for _, key := range keys {
|
||||
if _, ex := det.Fields[key]; ex {
|
||||
delete(det.Fields, key)
|
||||
if det.Has(key) {
|
||||
det.Delete(key)
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
|
@ -1707,9 +1684,9 @@ func (s *State) GetChangedStoreKeys(prefixPath ...string) (paths [][]string) {
|
|||
}
|
||||
|
||||
func (s *State) Layout() (model.ObjectTypeLayout, bool) {
|
||||
if det := s.Details(); det != nil && det.Fields != nil {
|
||||
if _, ok := det.Fields[bundle.RelationKeyLayout.String()]; ok {
|
||||
return model.ObjectTypeLayout(pbtypes.GetInt64(det, bundle.RelationKeyLayout.String())), true
|
||||
if det := s.Details(); det != nil {
|
||||
if det.Has(bundle.RelationKeyLayout) {
|
||||
return model.ObjectTypeLayout(det.GetInt64(bundle.RelationKeyLayout)), true
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
|
@ -1752,11 +1729,11 @@ func (s *State) GetRelationLinks() pbtypes.RelationLinks {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *State) RemoveRelation(keys ...string) {
|
||||
func (s *State) RemoveRelation(keys ...domain.RelationKey) {
|
||||
relLinks := s.GetRelationLinks()
|
||||
relLinksFiltered := make(pbtypes.RelationLinks, 0, len(relLinks))
|
||||
for _, link := range relLinks {
|
||||
if slice.FindPos(keys, link.Key) >= 0 {
|
||||
if slice.FindPos(keys, domain.RelationKey(link.Key)) >= 0 {
|
||||
continue
|
||||
}
|
||||
relLinksFiltered = append(relLinksFiltered, &model.RelationLink{
|
||||
|
@ -1768,16 +1745,16 @@ func (s *State) RemoveRelation(keys ...string) {
|
|||
s.RemoveDetail(keys...)
|
||||
// remove from the list of featured relations
|
||||
var foundInFeatured bool
|
||||
featuredList := pbtypes.GetStringList(s.Details(), bundle.RelationKeyFeaturedRelations.String())
|
||||
featuredList := s.Details().GetStringList(bundle.RelationKeyFeaturedRelations)
|
||||
featuredList = slice.Filter(featuredList, func(s string) bool {
|
||||
if slice.FindPos(keys, s) == -1 {
|
||||
if slice.FindPos(keys, domain.RelationKey(s)) == -1 {
|
||||
return true
|
||||
}
|
||||
foundInFeatured = true
|
||||
return false
|
||||
})
|
||||
if foundInFeatured {
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations.String(), pbtypes.StringList(featuredList))
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations, domain.StringList(featuredList))
|
||||
}
|
||||
s.relationLinks = relLinksFiltered
|
||||
return
|
||||
|
|
|
@ -192,7 +192,7 @@ func TestApplyState(t *testing.T) {
|
|||
s.InsertTo("4", model.Block_Bottom, "5")
|
||||
s.changeId = "4"
|
||||
|
||||
msgs, hist, err := ApplyState(s, true)
|
||||
msgs, hist, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, hist.Add, 2)
|
||||
assert.Len(t, hist.Change, 1)
|
||||
|
@ -206,11 +206,9 @@ func TestApplyState(t *testing.T) {
|
|||
})
|
||||
d.BlocksInit(d.(simple.DetailsService))
|
||||
s := d.NewState()
|
||||
s.SetDetails(&types.Struct{
|
||||
Fields: map[string]*types.Value{
|
||||
"name": pbtypes.String("new name"),
|
||||
},
|
||||
})
|
||||
s.SetDetails(domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
"name": domain.String("new name"),
|
||||
}))
|
||||
s.Add(text.NewDetails(&model.Block{
|
||||
Id: "title",
|
||||
Content: &model.BlockContentOfText{
|
||||
|
@ -225,7 +223,7 @@ func TestApplyState(t *testing.T) {
|
|||
Text: "name",
|
||||
Checked: "done",
|
||||
}))
|
||||
_, _, err := ApplyState(s, true)
|
||||
_, _, err := ApplyState("", s, true)
|
||||
assert.Equal(t, "new name", s.Pick("title").Model().GetText().Text)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
@ -248,12 +246,10 @@ func TestApplyState(t *testing.T) {
|
|||
})
|
||||
d.BlocksInit(d.(simple.DetailsService))
|
||||
s := d.NewState()
|
||||
s.SetDetails(&types.Struct{
|
||||
Fields: map[string]*types.Value{
|
||||
"name": pbtypes.String("new name"),
|
||||
},
|
||||
})
|
||||
msgs, _, err := ApplyState(s, true)
|
||||
s.SetDetails(domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
"name": domain.String("new name"),
|
||||
}))
|
||||
msgs, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2)
|
||||
})
|
||||
|
@ -274,15 +270,13 @@ func TestApplyState(t *testing.T) {
|
|||
Checked: "done",
|
||||
}),
|
||||
})
|
||||
d.(*State).SetDetail("done", pbtypes.Bool(true))
|
||||
d.(*State).SetDetail("done", domain.Bool(true))
|
||||
d.BlocksInit(d.(simple.DetailsService))
|
||||
s := d.NewState()
|
||||
s.SetDetails(&types.Struct{
|
||||
Fields: map[string]*types.Value{
|
||||
"done": pbtypes.Bool(false),
|
||||
},
|
||||
})
|
||||
msgs, _, err := ApplyState(s, true)
|
||||
s.SetDetails(domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
"done": domain.Bool(false),
|
||||
}))
|
||||
msgs, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2)
|
||||
})
|
||||
|
@ -303,11 +297,11 @@ func TestApplyState(t *testing.T) {
|
|||
Checked: "done",
|
||||
}),
|
||||
})
|
||||
d.(*State).SetDetail("done", pbtypes.Bool(true))
|
||||
d.(*State).SetDetail("done", domain.Bool(true))
|
||||
d.BlocksInit(d.(simple.DetailsService))
|
||||
s := d.NewState()
|
||||
s.Get("2").(text.Block).SetChecked(false)
|
||||
msgs, _, err := ApplyState(s, true)
|
||||
msgs, _, err := ApplyState("", s, true)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, msgs, 2)
|
||||
})
|
||||
|
@ -2101,7 +2095,7 @@ func TestState_ApplyChangeIgnoreErrDetailsSet(t *testing.T) {
|
|||
st.ApplyChangeIgnoreErr(change)
|
||||
|
||||
// then
|
||||
assert.Equal(t, "changed value", st.Details().GetFields()["relationKey"].GetStringValue())
|
||||
assert.Equal(t, "changed value", st.Details().GetString("relationKey"))
|
||||
})
|
||||
|
||||
t.Run("apply DetailsSet change: update existing relation", func(t *testing.T) {
|
||||
|
@ -2117,7 +2111,7 @@ func TestState_ApplyChangeIgnoreErrDetailsSet(t *testing.T) {
|
|||
st.ApplyChangeIgnoreErr(change)
|
||||
|
||||
// then
|
||||
assert.Equal(t, "value", st.Details().GetFields()["relationKey"].GetStringValue())
|
||||
assert.Equal(t, "value", st.Details().GetString("relationKey"))
|
||||
})
|
||||
|
||||
t.Run("apply DetailsSet change: set relation value to nil", func(t *testing.T) {
|
||||
|
@ -2133,7 +2127,7 @@ func TestState_ApplyChangeIgnoreErrDetailsSet(t *testing.T) {
|
|||
st.ApplyChangeIgnoreErr(change)
|
||||
|
||||
// then
|
||||
assert.Nil(t, st.Details().GetFields()["relationKey"])
|
||||
assert.False(t, st.Details().Has("relationKey"))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2156,12 +2150,12 @@ func TestState_ApplyChangeIgnoreErrDetailsUnset(t *testing.T) {
|
|||
st.ApplyChangeIgnoreErr(change)
|
||||
|
||||
// then
|
||||
assert.Nil(t, st.Details().GetFields()["relationKey"])
|
||||
assert.False(t, st.Details().Has("relationKey"))
|
||||
})
|
||||
|
||||
t.Run("apply DetailsUnset change: remove existing relation", func(t *testing.T) {
|
||||
// given
|
||||
st.SetDetail("relationKey", pbtypes.String("value"))
|
||||
st.SetDetail("relationKey", domain.String("value"))
|
||||
change := &pb.ChangeContent{Value: &pb.ChangeContentValueOfDetailsUnset{
|
||||
DetailsUnset: &pb.ChangeDetailsUnset{
|
||||
Key: "relationKey",
|
||||
|
@ -2172,7 +2166,7 @@ func TestState_ApplyChangeIgnoreErrDetailsUnset(t *testing.T) {
|
|||
st.ApplyChangeIgnoreErr(change)
|
||||
|
||||
// when
|
||||
assert.Nil(t, st.Details().GetFields()["relationKey"])
|
||||
assert.False(t, st.Details().Has("relationKey"))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2590,7 +2584,7 @@ func TestState_RootId(t *testing.T) {
|
|||
// detail := pbtypes.StringList([]string{"hello", "world", strings.Repeat("a", detailSizeLimit-9)})
|
||||
//
|
||||
// //when
|
||||
// s.SetDetail(bundle.RelationKeyType.String(), pbtypes.CopyVal(detail))
|
||||
// s.SetDetail(bundle.RelationKeyType, pbtypes.CopyVal(detail))
|
||||
//
|
||||
// //then
|
||||
// assert.Greater(t, detail.Size(), detailSizeLimit)
|
||||
|
@ -2845,7 +2839,7 @@ func TestState_FileRelationKeys(t *testing.T) {
|
|||
keys := s.FileRelationKeys()
|
||||
|
||||
// then
|
||||
expectedKeys := []string{"fileKey1", "fileKey2"}
|
||||
expectedKeys := []domain.RelationKey{"fileKey1", "fileKey2"}
|
||||
assert.ElementsMatch(t, keys, expectedKeys)
|
||||
})
|
||||
t.Run("duplicated file relations", func(t *testing.T) {
|
||||
|
@ -2861,7 +2855,7 @@ func TestState_FileRelationKeys(t *testing.T) {
|
|||
keys := s.FileRelationKeys()
|
||||
|
||||
// then
|
||||
expectedKeys := []string{"fileKey1"}
|
||||
expectedKeys := []domain.RelationKey{"fileKey1"}
|
||||
assert.ElementsMatch(t, keys, expectedKeys)
|
||||
})
|
||||
t.Run("coverId relation", func(t *testing.T) {
|
||||
|
@ -2870,17 +2864,16 @@ func TestState_FileRelationKeys(t *testing.T) {
|
|||
relationLinks: pbtypes.RelationLinks{
|
||||
{Key: bundle.RelationKeyCoverId.String()},
|
||||
},
|
||||
details: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyCoverType.String(): pbtypes.Int64(1),
|
||||
},
|
||||
},
|
||||
details: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyCoverType: domain.Int64(1),
|
||||
}),
|
||||
}
|
||||
|
||||
// when
|
||||
keys := s.FileRelationKeys()
|
||||
|
||||
// then
|
||||
expectedKeys := []string{bundle.RelationKeyCoverId.String()}
|
||||
expectedKeys := []domain.RelationKey{bundle.RelationKeyCoverId}
|
||||
assert.ElementsMatch(t, keys, expectedKeys)
|
||||
})
|
||||
t.Run("skip coverId relation", func(t *testing.T) {
|
||||
|
@ -2889,10 +2882,9 @@ func TestState_FileRelationKeys(t *testing.T) {
|
|||
relationLinks: pbtypes.RelationLinks{
|
||||
{Key: bundle.RelationKeyCoverId.String()},
|
||||
},
|
||||
details: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyCoverType.String(): pbtypes.Int64(2),
|
||||
},
|
||||
},
|
||||
details: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyCoverType: domain.Int64(2),
|
||||
}),
|
||||
}
|
||||
|
||||
// when
|
||||
|
@ -2907,10 +2899,9 @@ func TestState_FileRelationKeys(t *testing.T) {
|
|||
relationLinks: pbtypes.RelationLinks{
|
||||
{Key: bundle.RelationKeyCoverId.String()},
|
||||
},
|
||||
details: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyCoverType.String(): pbtypes.Int64(3),
|
||||
},
|
||||
},
|
||||
details: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyCoverType: domain.Int64(3),
|
||||
}),
|
||||
}
|
||||
|
||||
// when
|
||||
|
@ -2926,17 +2917,16 @@ func TestState_FileRelationKeys(t *testing.T) {
|
|||
{Format: model.RelationFormat_file, Key: "fileKey1"},
|
||||
{Key: bundle.RelationKeyCoverId.String()},
|
||||
},
|
||||
details: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyCoverType.String(): pbtypes.Int64(4),
|
||||
},
|
||||
},
|
||||
details: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyCoverType: domain.Int64(4),
|
||||
}),
|
||||
}
|
||||
|
||||
// when
|
||||
keys := s.FileRelationKeys()
|
||||
|
||||
// then
|
||||
expectedKeys := []string{"fileKey1", bundle.RelationKeyCoverId.String()}
|
||||
expectedKeys := []domain.RelationKey{"fileKey1", bundle.RelationKeyCoverId}
|
||||
assert.ElementsMatch(t, keys, expectedKeys, "Expected both file keys and cover ID")
|
||||
})
|
||||
t.Run("coverType not in details", func(t *testing.T) {
|
||||
|
|
|
@ -6,14 +6,13 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/template"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/link"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/text"
|
||||
"github.com/anyproto/anytype-heart/core/block/undo"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/event"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/metrics"
|
||||
|
@ -448,7 +447,7 @@ func (t *textImpl) TurnInto(ctx session.Context, style model.BlockContentTextSty
|
|||
textBlock, ok = b.(text.Block)
|
||||
if !ok {
|
||||
if linkBlock, ok := b.(link.Block); ok {
|
||||
var targetDetails *types.Struct
|
||||
var targetDetails *domain.Details
|
||||
if targetId := linkBlock.Model().GetLink().TargetBlockId; targetId != "" {
|
||||
// nolint:errcheck
|
||||
result, _ := t.objectStore.QueryByIds([]string{targetId})
|
||||
|
@ -480,7 +479,7 @@ func (t *textImpl) isLastTextBlockChanged() (bool, error) {
|
|||
return true, err
|
||||
}
|
||||
oldTextBlock := t.lastSetTextState.PickOrigin(t.lastSetTextId)
|
||||
messages, err := oldTextBlock.Diff(newTextBlock)
|
||||
messages, err := oldTextBlock.Diff(t.SpaceID(), newTextBlock)
|
||||
return len(messages) != 0, err
|
||||
}
|
||||
|
||||
|
|
|
@ -15,13 +15,13 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/simple/link"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/text"
|
||||
"github.com/anyproto/anytype-heart/core/block/undo"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/event/mock_event"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func newTextBlock(id, contentText string, childrenIds ...string) simple.Block {
|
||||
|
@ -548,8 +548,8 @@ func TestTextImpl_TurnInto(t *testing.T) {
|
|||
|
||||
os.AddObjects(t, []spaceindex.TestObject{
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("targetId"),
|
||||
bundle.RelationKeyName: pbtypes.String("link name"),
|
||||
bundle.RelationKeyId: domain.String("targetId"),
|
||||
bundle.RelationKeyName: domain.String("link name"),
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -571,7 +571,7 @@ func TestTextImpl_removeInternalFlags(t *testing.T) {
|
|||
sb := smarttest.New(rootID)
|
||||
sb.AddBlock(simple.New(&model.Block{Id: rootID, ChildrenIds: []string{blockID}})).
|
||||
AddBlock(newTextBlock(blockID, text))
|
||||
_ = sb.SetDetails(nil, []*model.Detail{{Key: bundle.RelationKeyInternalFlags.String(), Value: pbtypes.IntList(0, 1, 2)}}, false)
|
||||
_ = sb.SetDetails(nil, []domain.Detail{{Key: bundle.RelationKeyInternalFlags, Value: domain.Int64List([]int64{0, 1, 2})}}, false)
|
||||
tb := NewText(sb, nil, nil)
|
||||
|
||||
// when
|
||||
|
@ -584,7 +584,7 @@ func TestTextImpl_removeInternalFlags(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pbtypes.GetIntList(sb.Details(), bundle.RelationKeyInternalFlags.String()), 3)
|
||||
assert.Len(t, sb.Details().GetInt64List(bundle.RelationKeyInternalFlags), 3)
|
||||
})
|
||||
|
||||
t.Run("text is changed", func(t *testing.T) {
|
||||
|
@ -593,7 +593,7 @@ func TestTextImpl_removeInternalFlags(t *testing.T) {
|
|||
sb := smarttest.New(rootID)
|
||||
sb.AddBlock(simple.New(&model.Block{Id: rootID, ChildrenIds: []string{blockID}})).
|
||||
AddBlock(newTextBlock(blockID, text))
|
||||
_ = sb.SetDetails(nil, []*model.Detail{{Key: bundle.RelationKeyInternalFlags.String(), Value: pbtypes.IntList(0, 1, 2)}}, false)
|
||||
_ = sb.SetDetails(nil, []domain.Detail{{Key: bundle.RelationKeyInternalFlags, Value: domain.Int64List([]int64{0, 1, 2})}}, false)
|
||||
tb := NewText(sb, nil, nil)
|
||||
|
||||
// when
|
||||
|
@ -606,7 +606,7 @@ func TestTextImpl_removeInternalFlags(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, pbtypes.GetIntList(sb.Details(), bundle.RelationKeyInternalFlags.String()))
|
||||
assert.Empty(t, sb.Details().GetInt64List(bundle.RelationKeyInternalFlags))
|
||||
})
|
||||
|
||||
t.Run("marks are changed", func(t *testing.T) {
|
||||
|
@ -615,7 +615,7 @@ func TestTextImpl_removeInternalFlags(t *testing.T) {
|
|||
sb := smarttest.New(rootID)
|
||||
sb.AddBlock(simple.New(&model.Block{Id: rootID, ChildrenIds: []string{blockID}})).
|
||||
AddBlock(newTextBlock(blockID, text))
|
||||
_ = sb.SetDetails(nil, []*model.Detail{{Key: bundle.RelationKeyInternalFlags.String(), Value: pbtypes.IntList(0, 1, 2)}}, false)
|
||||
_ = sb.SetDetails(nil, []domain.Detail{{Key: bundle.RelationKeyInternalFlags, Value: domain.Int64List([]int64{0, 1, 2})}}, false)
|
||||
tb := NewText(sb, nil, nil)
|
||||
|
||||
// when
|
||||
|
@ -629,7 +629,7 @@ func TestTextImpl_removeInternalFlags(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, pbtypes.GetIntList(sb.Details(), bundle.RelationKeyInternalFlags.String()))
|
||||
assert.Empty(t, sb.Details().GetInt64List(bundle.RelationKeyInternalFlags))
|
||||
})
|
||||
|
||||
t.Run("title is changed", func(t *testing.T) {
|
||||
|
@ -638,7 +638,7 @@ func TestTextImpl_removeInternalFlags(t *testing.T) {
|
|||
sb := smarttest.New(rootID)
|
||||
sb.AddBlock(simple.New(&model.Block{Id: rootID, ChildrenIds: []string{template.TitleBlockId}})).
|
||||
AddBlock(newTextBlock(template.TitleBlockId, text))
|
||||
_ = sb.SetDetails(nil, []*model.Detail{{Key: bundle.RelationKeyInternalFlags.String(), Value: pbtypes.IntList(0, 1, 2)}}, false)
|
||||
_ = sb.SetDetails(nil, []domain.Detail{{Key: bundle.RelationKeyInternalFlags, Value: domain.Int64List([]int64{0, 1, 2})}}, false)
|
||||
tb := NewText(sb, nil, nil)
|
||||
|
||||
// when
|
||||
|
@ -651,7 +651,7 @@ func TestTextImpl_removeInternalFlags(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
flags := pbtypes.GetIntList(sb.Details(), bundle.RelationKeyInternalFlags.String())
|
||||
flags := sb.Details().GetInt64List(bundle.RelationKeyInternalFlags)
|
||||
assert.Len(t, flags, 2)
|
||||
assert.NotContains(t, flags, model.InternalFlag_editorDeleteEmpty)
|
||||
})
|
||||
|
|
|
@ -53,10 +53,10 @@ func (m *subObjectsMigration) migrateSubObjects(st *state.State) {
|
|||
return
|
||||
}
|
||||
|
||||
if pbtypes.GetBool(info.Details, migratedKey) {
|
||||
if info.Details.GetBool(migratedKey) {
|
||||
return
|
||||
}
|
||||
uniqueKeyRaw := pbtypes.GetString(info.Details, bundle.RelationKeyUniqueKey.String())
|
||||
uniqueKeyRaw := info.Details.GetString(bundle.RelationKeyUniqueKey)
|
||||
id, err := m.migrateSubObject(context.Background(), uniqueKeyRaw, info.Details, info.Type)
|
||||
if err != nil && !errors.Is(err, treestorage.ErrTreeExists) {
|
||||
log.With("objectID", id).Errorf("failed to migrate subobject: %v", err)
|
||||
|
@ -68,7 +68,7 @@ func (m *subObjectsMigration) migrateSubObjects(st *state.State) {
|
|||
needToAddRestrictions := false
|
||||
switch info.Type {
|
||||
case bundle.TypeKeyRelation:
|
||||
format := pbtypes.GetInt64(info.Details, bundle.RelationKeyRelationFormat.String())
|
||||
format := info.Details.GetInt64(bundle.RelationKeyRelationFormat)
|
||||
if format == int64(model.RelationFormat_tag) || format == int64(model.RelationFormat_status) {
|
||||
// tags and statuses relations values are become readonly
|
||||
st.SetInStore(append(path, bundle.RelationKeyRelationReadonlyValue.String()), pbtypes.Bool(true))
|
||||
|
@ -95,7 +95,7 @@ func (m *subObjectsMigration) migrateSubObjects(st *state.State) {
|
|||
if needToAddRestrictions {
|
||||
// we can't add restrictions as it can lead to removing this field on the old client
|
||||
// todo: revise this
|
||||
// st.SetInStore(append(path, bundle.RelationKeyRestrictions.String()), pbtypes.IntList(1, 3, 4))
|
||||
// st.SetInStore(append(path, bundle.RelationKeyRestrictions.TryString()), pbtypes.TryInt64List(1, 3, 4))
|
||||
}
|
||||
|
||||
migratedSubObjects++
|
||||
|
@ -114,7 +114,7 @@ func (m *subObjectsMigration) migrateSubObjects(st *state.State) {
|
|||
func (m *subObjectsMigration) migrateSubObject(
|
||||
ctx context.Context,
|
||||
uniqueKeyRaw string,
|
||||
details *types.Struct,
|
||||
details *domain.Details,
|
||||
typeKey domain.TypeKey,
|
||||
) (id string, err error) {
|
||||
uniqueKey, err := domain.UnmarshalUniqueKey(uniqueKeyRaw)
|
||||
|
@ -181,8 +181,8 @@ func (m *subObjectsMigration) iterateAllSubObjects(st *state.State, proc func(in
|
|||
continue
|
||||
}
|
||||
|
||||
details := v.StructValue
|
||||
details.Fields[bundle.RelationKeyUniqueKey.String()] = pbtypes.String(uk.Marshal())
|
||||
details := domain.NewDetailsFromProto(v.StructValue)
|
||||
details.SetString(bundle.RelationKeyUniqueKey, uk.Marshal())
|
||||
|
||||
proc(smartblock.DocInfo{
|
||||
Links: nil,
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
type Template struct {
|
||||
|
@ -41,7 +40,7 @@ func (t *Template) CreationStateMigration(ctx *smartblock.InitContext) migration
|
|||
Version: 1,
|
||||
Proc: func(s *state.State) {
|
||||
if t.Type() == coresb.SmartBlockTypeTemplate && (len(t.ObjectTypeKeys()) != 2) {
|
||||
targetObjectTypeId := pbtypes.GetString(s.Details(), bundle.RelationKeyTargetObjectType.String())
|
||||
targetObjectTypeId := s.Details().GetString(bundle.RelationKeyTargetObjectType)
|
||||
if targetObjectTypeId != "" {
|
||||
uniqueKey, err := t.objectStore.GetUniqueKeyById(targetObjectTypeId)
|
||||
if err == nil && uniqueKey.SmartblockType() != coresb.SmartBlockTypeObjectType {
|
||||
|
|
|
@ -98,38 +98,38 @@ var WithObjectTypesAndLayout = func(otypes []domain.TypeKey, layout model.Object
|
|||
otypes = s.ObjectTypeKeys()
|
||||
}
|
||||
|
||||
if !pbtypes.HasField(s.Details(), bundle.RelationKeyLayout.String()) {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyLayout, pbtypes.Float64(float64(layout)))
|
||||
if !s.Details().Has(bundle.RelationKeyLayout) {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeyLayout, domain.Int64(layout))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var WithLayout = func(layout model.ObjectTypeLayout) StateTransformer {
|
||||
return WithDetail(bundle.RelationKeyLayout, pbtypes.Float64(float64(layout)))
|
||||
return WithDetail(bundle.RelationKeyLayout, domain.Int64(layout))
|
||||
}
|
||||
|
||||
var WithDetailName = func(name string) StateTransformer {
|
||||
return WithDetail(bundle.RelationKeyName, pbtypes.String(name))
|
||||
return WithDetail(bundle.RelationKeyName, domain.String(name))
|
||||
}
|
||||
|
||||
var WithDetail = func(key domain.RelationKey, value *types.Value) StateTransformer {
|
||||
var WithDetail = func(key domain.RelationKey, value domain.Value) StateTransformer {
|
||||
return func(s *state.State) {
|
||||
if s.Details() == nil || s.Details().Fields == nil || s.Details().Fields[key.String()] == nil {
|
||||
if s.Details() == nil || !s.Details().Has(key) {
|
||||
s.SetDetailAndBundledRelation(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var WithForcedDetail = func(key domain.RelationKey, value *types.Value) StateTransformer {
|
||||
var WithForcedDetail = func(key domain.RelationKey, value domain.Value) StateTransformer {
|
||||
return func(s *state.State) {
|
||||
if s.Details() == nil || s.Details().Fields == nil || s.Details().Fields[key.String()] == nil || !s.Details().Fields[key.String()].Equal(value) {
|
||||
if s.Details() == nil || !s.Details().Has(key) || !s.Details().Get(key).Equal(value) {
|
||||
s.SetDetailAndBundledRelation(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var WithDetailIconEmoji = func(iconEmoji string) StateTransformer {
|
||||
return WithDetail(bundle.RelationKeyIconEmoji, pbtypes.String(iconEmoji))
|
||||
return WithDetail(bundle.RelationKeyIconEmoji, domain.String(iconEmoji))
|
||||
}
|
||||
|
||||
var RequireHeader = StateTransformer(func(s *state.State) {
|
||||
|
@ -172,8 +172,8 @@ var WithTitle = StateTransformer(func(s *state.State) {
|
|||
var (
|
||||
align model.BlockAlign
|
||||
)
|
||||
if pbtypes.HasField(s.Details(), bundle.RelationKeyLayoutAlign.String()) {
|
||||
alignN := int32(pbtypes.GetFloat64(s.Details(), bundle.RelationKeyLayoutAlign.String()))
|
||||
if s.Details().Has(bundle.RelationKeyLayoutAlign) {
|
||||
alignN := int32(s.Details().GetInt64(bundle.RelationKeyLayoutAlign))
|
||||
if alignN >= 0 && alignN <= 2 {
|
||||
align = model.BlockAlign(alignN)
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ var WithTitle = StateTransformer(func(s *state.State) {
|
|||
|
||||
// WithDefaultFeaturedRelations **MUST** be called before WithDescription
|
||||
var WithDefaultFeaturedRelations = func(s *state.State) {
|
||||
if !pbtypes.HasField(s.Details(), bundle.RelationKeyFeaturedRelations.String()) {
|
||||
if !s.Details().Has(bundle.RelationKeyFeaturedRelations) {
|
||||
var fr = []string{bundle.RelationKeyType.String()}
|
||||
layout, _ := s.Layout()
|
||||
switch layout {
|
||||
|
@ -234,41 +234,43 @@ var WithDefaultFeaturedRelations = func(s *state.State) {
|
|||
fr = []string{bundle.RelationKeyType.String(), bundle.RelationKeyBacklinks.String()}
|
||||
case model.ObjectType_file, model.ObjectType_image, model.ObjectType_audio, model.ObjectType_video:
|
||||
fr = []string{bundle.RelationKeyType.String(), bundle.RelationKeyTag.String(), bundle.RelationKeyBacklinks.String()}
|
||||
// Tag is not added to details of object explicitly as it is not system relation
|
||||
s.SetDetail(bundle.RelationKeyTag, domain.StringList([]string{}))
|
||||
}
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations.String(), pbtypes.StringList(fr))
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations, domain.StringList(fr))
|
||||
}
|
||||
}
|
||||
|
||||
var WithAddedFeaturedRelation = func(key domain.RelationKey) StateTransformer {
|
||||
return func(s *state.State) {
|
||||
var featRels = pbtypes.GetStringList(s.Details(), bundle.RelationKeyFeaturedRelations.String())
|
||||
featRels := s.Details().GetStringList(bundle.RelationKeyFeaturedRelations)
|
||||
if slice.FindPos(featRels, key.String()) > -1 {
|
||||
return
|
||||
} else {
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations.String(), pbtypes.StringList(append(featRels, key.String())))
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations, domain.StringList(append(featRels, key.String())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var WithRemovedFeaturedRelation = func(key domain.RelationKey) StateTransformer {
|
||||
return func(s *state.State) {
|
||||
var featRels = pbtypes.GetStringList(s.Details(), bundle.RelationKeyFeaturedRelations.String())
|
||||
var featRels = s.Details().GetStringList(bundle.RelationKeyFeaturedRelations)
|
||||
if slice.FindPos(featRels, key.String()) > -1 {
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations.String(), pbtypes.StringList(slice.RemoveMut(featRels, key.String())))
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations, domain.StringList(slice.RemoveMut(featRels, key.String())))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var WithCreatorRemovedFromFeaturedRelations = StateTransformer(func(s *state.State) {
|
||||
fr := pbtypes.GetStringList(s.Details(), bundle.RelationKeyFeaturedRelations.String())
|
||||
fr := s.Details().GetStringList(bundle.RelationKeyFeaturedRelations)
|
||||
|
||||
if slice.FindPos(fr, bundle.RelationKeyCreator.String()) != -1 {
|
||||
frc := make([]string, len(fr))
|
||||
copy(frc, fr)
|
||||
|
||||
frc = slice.RemoveMut(frc, bundle.RelationKeyCreator.String())
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations.String(), pbtypes.StringList(frc))
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations, domain.StringList(frc))
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -276,8 +278,8 @@ var WithForcedDescription = func(s *state.State) {
|
|||
RequireHeader(s)
|
||||
|
||||
var align model.BlockAlign
|
||||
if pbtypes.HasField(s.Details(), bundle.RelationKeyLayoutAlign.String()) {
|
||||
alignN := int(pbtypes.GetFloat64(s.Details(), bundle.RelationKeyLayoutAlign.String()))
|
||||
if s.Details().Has(bundle.RelationKeyLayoutAlign) {
|
||||
alignN := int(s.Details().GetFloat64(bundle.RelationKeyLayoutAlign))
|
||||
if alignN >= 0 && alignN <= 2 {
|
||||
align = model.BlockAlign(alignN)
|
||||
}
|
||||
|
@ -365,11 +367,11 @@ var WithNoDescription = StateTransformer(func(s *state.State) {
|
|||
var WithNameToFirstBlock = StateTransformer(func(s *state.State) {
|
||||
RequireHeader(s)
|
||||
|
||||
name, ok := s.Details().Fields[bundle.RelationKeyName.String()]
|
||||
if ok && name.GetStringValue() != "" {
|
||||
name, ok := s.Details().TryString(bundle.RelationKeyName)
|
||||
if ok && name != "" {
|
||||
newBlock := simple.New(&model.Block{
|
||||
Content: &model.BlockContentOfText{
|
||||
Text: &model.BlockContentText{Text: name.GetStringValue()},
|
||||
Text: &model.BlockContentText{Text: name},
|
||||
},
|
||||
})
|
||||
s.Add(newBlock)
|
||||
|
@ -377,7 +379,7 @@ var WithNameToFirstBlock = StateTransformer(func(s *state.State) {
|
|||
if err := s.InsertTo(HeaderLayoutId, model.Block_Bottom, newBlock.Model().Id); err != nil {
|
||||
log.Errorf("WithNameToFirstBlock failed to insert: %s", err)
|
||||
} else {
|
||||
s.RemoveDetail(bundle.RelationKeyName.String())
|
||||
s.RemoveDetail(bundle.RelationKeyName)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -386,8 +388,8 @@ var WithFeaturedRelations = StateTransformer(func(s *state.State) {
|
|||
RequireHeader(s)
|
||||
|
||||
var align model.BlockAlign
|
||||
if pbtypes.HasField(s.Details(), bundle.RelationKeyLayoutAlign.String()) {
|
||||
alignN := int(pbtypes.GetFloat64(s.Details(), bundle.RelationKeyLayoutAlign.String()))
|
||||
if s.Details().Has(bundle.RelationKeyLayoutAlign) {
|
||||
alignN := int(s.Details().GetFloat64(bundle.RelationKeyLayoutAlign))
|
||||
if alignN >= 0 && alignN <= 2 {
|
||||
align = model.BlockAlign(alignN)
|
||||
}
|
||||
|
@ -493,45 +495,6 @@ var WithDataview = func(dataview *model.BlockContentOfDataview, forceViews bool)
|
|||
return WithDataviewID(DataviewBlockId, dataview, forceViews)
|
||||
}
|
||||
|
||||
var WithNoRootLink = func(targetBlockId string) StateTransformer {
|
||||
return func(s *state.State) {
|
||||
var linkBlockId string
|
||||
s.Iterate(func(b simple.Block) (isContinue bool) {
|
||||
if b, ok := b.(*link.Link); !ok {
|
||||
return true
|
||||
} else {
|
||||
if b.Model().GetLink().TargetBlockId == targetBlockId {
|
||||
linkBlockId = b.Id
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
if linkBlockId == "" {
|
||||
return
|
||||
}
|
||||
|
||||
s.Unlink(linkBlockId)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func WithBlockField(blockId, fieldName string, value *types.Value) StateTransformer {
|
||||
return func(s *state.State) {
|
||||
if b := s.Get(blockId); b != nil {
|
||||
fields := b.Model().Fields
|
||||
if fields == nil || fields.Fields == nil {
|
||||
fields = &types.Struct{Fields: map[string]*types.Value{}}
|
||||
}
|
||||
fields.Fields[fieldName] = value
|
||||
b.Model().Fields = fields
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func InitTemplate(s *state.State, templates ...StateTransformer) {
|
||||
for _, template := range templates {
|
||||
template(s)
|
||||
|
@ -595,8 +558,8 @@ var oldBookmarkRelationBlocks = []string{
|
|||
bundle.RelationKeyCreatedDate.String(),
|
||||
}
|
||||
|
||||
var oldBookmarkRelations = []string{
|
||||
bundle.RelationKeyUrl.String(),
|
||||
var oldBookmarkRelations = []domain.RelationKey{
|
||||
bundle.RelationKeyUrl,
|
||||
}
|
||||
|
||||
func makeRelationBlock(k string) *model.Block {
|
||||
|
@ -612,7 +575,8 @@ func makeRelationBlock(k string) *model.Block {
|
|||
|
||||
var WithBookmarkBlocks = func(s *state.State) {
|
||||
if !s.HasRelation(bundle.RelationKeySource.String()) && s.HasRelation(bundle.RelationKeyUrl.String()) {
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeySource, s.Details().Fields[bundle.RelationKeyUrl.String()])
|
||||
url := s.Details().GetString(bundle.RelationKeyUrl)
|
||||
s.SetDetailAndBundledRelation(bundle.RelationKeySource, domain.String(url))
|
||||
}
|
||||
|
||||
for _, oldRel := range oldBookmarkRelationBlocks {
|
||||
|
@ -623,11 +587,11 @@ var WithBookmarkBlocks = func(s *state.State) {
|
|||
s.RemoveRelation(oldRel)
|
||||
}
|
||||
|
||||
fr := pbtypes.GetStringList(s.Details(), bundle.RelationKeyFeaturedRelations.String())
|
||||
fr := s.Details().GetStringList(bundle.RelationKeyFeaturedRelations)
|
||||
|
||||
if slice.FindPos(fr, bundle.RelationKeyCreatedDate.String()) == -1 {
|
||||
fr = append(fr, bundle.RelationKeyCreatedDate.String())
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations.String(), pbtypes.StringList(fr))
|
||||
s.SetDetail(bundle.RelationKeyFeaturedRelations, domain.StringList(fr))
|
||||
}
|
||||
|
||||
for _, k := range bookmarkRelationKeys {
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
type WidgetObject struct {
|
||||
|
@ -55,7 +54,7 @@ func (w *WidgetObject) CreationStateMigration(ctx *smartblock.InitContext) migra
|
|||
template.InitTemplate(st,
|
||||
template.WithEmpty,
|
||||
template.WithObjectTypesAndLayout([]domain.TypeKey{bundle.TypeKeyDashboard}, model.ObjectType_dashboard),
|
||||
template.WithDetail(bundle.RelationKeyIsHidden, pbtypes.Bool(true)),
|
||||
template.WithDetail(bundle.RelationKeyIsHidden, domain.Bool(true)),
|
||||
)
|
||||
},
|
||||
}
|
||||
|
|
|
@ -79,10 +79,10 @@ func (w *Workspaces) initTemplate(ctx *smartblock.InitContext) {
|
|||
template.WithEmpty,
|
||||
template.WithTitle,
|
||||
template.WithFeaturedRelations,
|
||||
template.WithDetail(bundle.RelationKeyIsHidden, pbtypes.Bool(true)),
|
||||
template.WithForcedDetail(bundle.RelationKeyLayout, pbtypes.Float64(float64(model.ObjectType_space))),
|
||||
template.WithDetail(bundle.RelationKeyIsHidden, domain.Bool(true)),
|
||||
template.WithForcedDetail(bundle.RelationKeyLayout, domain.Int64(model.ObjectType_space)),
|
||||
template.WithForcedObjectTypes([]domain.TypeKey{bundle.TypeKeySpace}),
|
||||
template.WithForcedDetail(bundle.RelationKeyFeaturedRelations, pbtypes.StringList([]string{bundle.RelationKeyType.String(), bundle.RelationKeyCreator.String()})),
|
||||
template.WithForcedDetail(bundle.RelationKeyFeaturedRelations, domain.StringList([]string{bundle.RelationKeyType.String(), bundle.RelationKeyCreator.String()})),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -98,23 +98,23 @@ func (w *Workspaces) CreationStateMigration(ctx *smartblock.InitContext) migrati
|
|||
|
||||
func (w *Workspaces) SetInviteFileInfo(fileCid string, fileKey string) (err error) {
|
||||
st := w.NewState()
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceInviteFileCid, pbtypes.String(fileCid))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceInviteFileKey, pbtypes.String(fileKey))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceInviteFileCid, domain.String(fileCid))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceInviteFileKey, domain.String(fileKey))
|
||||
return w.Apply(st)
|
||||
}
|
||||
|
||||
func (w *Workspaces) GetExistingInviteInfo() (fileCid string, fileKey string) {
|
||||
details := w.CombinedDetails()
|
||||
fileCid = pbtypes.GetString(details, bundle.RelationKeySpaceInviteFileCid.String())
|
||||
fileKey = pbtypes.GetString(details, bundle.RelationKeySpaceInviteFileKey.String())
|
||||
fileCid = details.GetString(bundle.RelationKeySpaceInviteFileCid)
|
||||
fileKey = details.GetString(bundle.RelationKeySpaceInviteFileKey)
|
||||
return
|
||||
}
|
||||
|
||||
func (w *Workspaces) RemoveExistingInviteInfo() (fileCid string, err error) {
|
||||
details := w.Details()
|
||||
fileCid = pbtypes.GetString(details, bundle.RelationKeySpaceInviteFileCid.String())
|
||||
fileCid = details.GetString(bundle.RelationKeySpaceInviteFileCid)
|
||||
newState := w.NewState()
|
||||
newState.RemoveDetail(bundle.RelationKeySpaceInviteFileCid.String(), bundle.RelationKeySpaceInviteFileKey.String())
|
||||
newState.RemoveDetail(bundle.RelationKeySpaceInviteFileCid, bundle.RelationKeySpaceInviteFileKey)
|
||||
return fileCid, w.Apply(newState)
|
||||
}
|
||||
|
||||
|
@ -128,6 +128,6 @@ func (w *Workspaces) onApply(info smartblock.ApplyInfo) error {
|
|||
}
|
||||
|
||||
func (w *Workspaces) onWorkspaceChanged(state *state.State) {
|
||||
details := pbtypes.CopyStruct(state.CombinedDetails(), true)
|
||||
details := state.CombinedDetails().Copy()
|
||||
w.spaceService.OnWorkspaceChanged(w.SpaceID(), details)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/google/uuid"
|
||||
"github.com/gosimple/slug"
|
||||
"github.com/samber/lo"
|
||||
|
@ -46,7 +45,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/space/spacecore/typeprovider"
|
||||
"github.com/anyproto/anytype-heart/util/anyerror"
|
||||
"github.com/anyproto/anytype-heart/util/constant"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/text"
|
||||
)
|
||||
|
||||
|
@ -145,7 +143,7 @@ func (e *export) sendNotification(err error, req pb.RpcObjectListExportRequest)
|
|||
|
||||
type exportContext struct {
|
||||
spaceId string
|
||||
docs map[string]*types.Struct
|
||||
docs map[string]*domain.Details
|
||||
includeArchive bool
|
||||
includeNested bool
|
||||
includeFiles bool
|
||||
|
@ -162,7 +160,7 @@ func newExportContext(e *export, req pb.RpcObjectListExportRequest) *exportConte
|
|||
return &exportContext{
|
||||
path: req.Path,
|
||||
spaceId: req.SpaceId,
|
||||
docs: map[string]*types.Struct{},
|
||||
docs: map[string]*domain.Details{},
|
||||
includeArchive: req.IncludeArchived,
|
||||
includeNested: req.IncludeNested,
|
||||
includeFiles: req.IncludeFiles,
|
||||
|
@ -328,12 +326,12 @@ func (e *exportContext) docsForExport() (err error) {
|
|||
}
|
||||
|
||||
func (e *exportContext) getObjectsByIDs(isProtobuf bool) error {
|
||||
res, err := e.queryAndFilterObjectsByRelation(e.spaceId, e.reqIds, bundle.RelationKeyId.String())
|
||||
res, err := e.queryAndFilterObjectsByRelation(e.spaceId, e.reqIds, bundle.RelationKeyId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, object := range res {
|
||||
id := pbtypes.GetString(object.Details, bundle.RelationKeyId.String())
|
||||
id := object.Details.GetString(bundle.RelationKeyId)
|
||||
e.docs[id] = object.Details
|
||||
}
|
||||
if isProtobuf {
|
||||
|
@ -342,18 +340,18 @@ func (e *exportContext) getObjectsByIDs(isProtobuf bool) error {
|
|||
return e.processNotProtobuf()
|
||||
}
|
||||
|
||||
func (e *exportContext) queryAndFilterObjectsByRelation(spaceId string, reqIds []string, relationFilter string) ([]database.Record, error) {
|
||||
func (e *exportContext) queryAndFilterObjectsByRelation(spaceId string, reqIds []string, relationKey domain.RelationKey) ([]database.Record, error) {
|
||||
var allObjects []database.Record
|
||||
const singleBatchCount = 50
|
||||
for j := 0; j < len(reqIds); {
|
||||
if j+singleBatchCount < len(reqIds) {
|
||||
records, err := e.queryObjectsByIds(spaceId, reqIds[j:j+singleBatchCount], relationFilter)
|
||||
records, err := e.queryObjectsByIds(spaceId, reqIds[j:j+singleBatchCount], relationKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allObjects = append(allObjects, records...)
|
||||
} else {
|
||||
records, err := e.queryObjectsByIds(spaceId, reqIds[j:], relationFilter)
|
||||
records, err := e.queryObjectsByIds(spaceId, reqIds[j:], relationKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -364,13 +362,13 @@ func (e *exportContext) queryAndFilterObjectsByRelation(spaceId string, reqIds [
|
|||
return allObjects, nil
|
||||
}
|
||||
|
||||
func (e *exportContext) queryObjectsByIds(spaceId string, reqIds []string, relationFilter string) ([]database.Record, error) {
|
||||
func (e *exportContext) queryObjectsByIds(spaceId string, reqIds []string, relationKey domain.RelationKey) ([]database.Record, error) {
|
||||
return e.objectStore.SpaceIndex(spaceId).Query(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
RelationKey: relationFilter,
|
||||
RelationKey: relationKey,
|
||||
Condition: model.BlockContentDataviewFilter_In,
|
||||
Value: pbtypes.StringList(reqIds),
|
||||
Value: domain.StringList(reqIds),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -387,7 +385,7 @@ func (e *exportContext) processNotProtobuf() error {
|
|||
}
|
||||
if e.includeNested {
|
||||
for _, id := range ids {
|
||||
e.addNestedObject(id, map[string]*types.Struct{})
|
||||
e.addNestedObject(id, map[string]*domain.Details{})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -461,7 +459,7 @@ func (e *exportContext) addDerivedObjects() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (e *exportContext) getRelationsAndTypes(notProcessedObjects map[string]*types.Struct, processedObjects map[string]struct{}) ([]string, []string, []string, error) {
|
||||
func (e *exportContext) getRelationsAndTypes(notProcessedObjects map[string]*domain.Details, processedObjects map[string]struct{}) ([]string, []string, []string, error) {
|
||||
allRelations, allTypes, allSetOfList, err := e.collectDerivedObjects(notProcessedObjects)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
|
@ -480,7 +478,7 @@ func (e *exportContext) getRelationsAndTypes(notProcessedObjects map[string]*typ
|
|||
return allRelations, allTypes, allSetOfList, nil
|
||||
}
|
||||
|
||||
func (e *exportContext) collectDerivedObjects(objects map[string]*types.Struct) ([]string, []string, []string, error) {
|
||||
func (e *exportContext) collectDerivedObjects(objects map[string]*domain.Details) ([]string, []string, []string, error) {
|
||||
var relations, objectsTypes, setOf []string
|
||||
for id := range objects {
|
||||
err := cache.Do(e.picker, id, func(b sb.SmartBlock) error {
|
||||
|
@ -494,9 +492,9 @@ func (e *exportContext) collectDerivedObjects(objects map[string]*types.Struct)
|
|||
}
|
||||
relations = lo.Union(relations, dataviewRelations)
|
||||
}
|
||||
objectTypeId := pbtypes.GetString(details, bundle.RelationKeyType.String())
|
||||
objectTypeId := details.GetString(bundle.RelationKeyType)
|
||||
objectsTypes = lo.Union(objectsTypes, []string{objectTypeId})
|
||||
setOfList := pbtypes.GetStringList(details, bundle.RelationKeySetOf.String())
|
||||
setOfList := details.GetStringList(bundle.RelationKeySetOf)
|
||||
setOf = lo.Union(setOf, setOfList)
|
||||
return nil
|
||||
})
|
||||
|
@ -516,9 +514,9 @@ func getObjectRelations(state *state.State) []string {
|
|||
return relations
|
||||
}
|
||||
|
||||
func isObjectWithDataview(details *types.Struct) bool {
|
||||
return pbtypes.GetFloat64(details, bundle.RelationKeyLayout.String()) == float64(model.ObjectType_collection) ||
|
||||
pbtypes.GetFloat64(details, bundle.RelationKeyLayout.String()) == float64(model.ObjectType_set)
|
||||
func isObjectWithDataview(details *domain.Details) bool {
|
||||
return details.GetInt64(bundle.RelationKeyLayout) == int64(model.ObjectType_collection) ||
|
||||
details.GetInt64(bundle.RelationKeyLayout) == int64(model.ObjectType_set)
|
||||
}
|
||||
|
||||
func getDataviewRelations(state *state.State) ([]string, error) {
|
||||
|
@ -537,7 +535,7 @@ func getDataviewRelations(state *state.State) ([]string, error) {
|
|||
}
|
||||
|
||||
func (e *exportContext) getDerivedObjectsForTypes(allTypes []string, processedObjects map[string]struct{}) ([]string, []string, []string, error) {
|
||||
notProceedTypes := make(map[string]*types.Struct)
|
||||
notProceedTypes := make(map[string]*domain.Details)
|
||||
var relations, objectTypes []string
|
||||
for _, object := range allTypes {
|
||||
if _, ok := processedObjects[object]; ok {
|
||||
|
@ -557,16 +555,16 @@ func (e *exportContext) getDerivedObjectsForTypes(allTypes []string, processedOb
|
|||
}
|
||||
|
||||
func (e *exportContext) getTemplatesRelationsAndTypes(allTypes []string, processedObjects map[string]struct{}) ([]string, []string, []string, error) {
|
||||
templates, err := e.queryAndFilterObjectsByRelation(e.spaceId, allTypes, bundle.RelationKeyTargetObjectType.String())
|
||||
templates, err := e.queryAndFilterObjectsByRelation(e.spaceId, allTypes, bundle.RelationKeyTargetObjectType)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
if len(templates) == 0 {
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
templatesToProcess := make(map[string]*types.Struct, len(templates))
|
||||
templatesToProcess := make(map[string]*domain.Details, len(templates))
|
||||
for _, template := range templates {
|
||||
id := pbtypes.GetString(template.Details, bundle.RelationKeyId.String())
|
||||
id := template.Details.GetString(bundle.RelationKeyId)
|
||||
if _, ok := e.docs[id]; !ok {
|
||||
e.docs[id] = template.Details
|
||||
templatesToProcess[id] = template.Details
|
||||
|
@ -615,7 +613,7 @@ func (e *exportContext) getRelationsFromStore(relations []string) ([]database.Re
|
|||
}
|
||||
uniqueKeys = append(uniqueKeys, uniqueKey.Marshal())
|
||||
}
|
||||
storeRelations, err := e.queryAndFilterObjectsByRelation(e.spaceId, uniqueKeys, bundle.RelationKeyUniqueKey.String())
|
||||
storeRelations, err := e.queryAndFilterObjectsByRelation(e.spaceId, uniqueKeys, bundle.RelationKeyUniqueKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -623,17 +621,16 @@ func (e *exportContext) getRelationsFromStore(relations []string) ([]database.Re
|
|||
}
|
||||
|
||||
func (e *exportContext) addRelation(relation database.Record) {
|
||||
if relationKey := pbtypes.GetString(relation.Details, bundle.RelationKeyRelationKey.String()); relationKey != "" {
|
||||
if !bundle.HasRelation(relationKey) {
|
||||
id := pbtypes.GetString(relation.Details, bundle.RelationKeyId.String())
|
||||
e.docs[id] = relation.Details
|
||||
}
|
||||
relationKey := domain.RelationKey(relation.Details.GetString(bundle.RelationKeyRelationKey))
|
||||
if relationKey != "" && !bundle.HasRelation(relationKey) {
|
||||
id := relation.Details.GetString(bundle.RelationKeyId)
|
||||
e.docs[id] = relation.Details
|
||||
}
|
||||
}
|
||||
|
||||
func (e *exportContext) addOptionIfTag(relation database.Record) error {
|
||||
format := pbtypes.GetInt64(relation.Details, bundle.RelationKeyRelationFormat.String())
|
||||
relationKey := pbtypes.GetString(relation.Details, bundle.RelationKeyRelationKey.String())
|
||||
format := relation.Details.GetInt64(bundle.RelationKeyRelationFormat)
|
||||
relationKey := relation.Details.GetString(bundle.RelationKeyRelationKey)
|
||||
if format == int64(model.RelationFormat_tag) || format == int64(model.RelationFormat_status) {
|
||||
err := e.addRelationOptions(relationKey)
|
||||
if err != nil {
|
||||
|
@ -649,7 +646,7 @@ func (e *exportContext) addRelationOptions(relationKey string) error {
|
|||
return err
|
||||
}
|
||||
for _, option := range relationOptions {
|
||||
id := pbtypes.GetString(option.Details, bundle.RelationKeyId.String())
|
||||
id := option.Details.GetString(bundle.RelationKeyId)
|
||||
e.docs[id] = option.Details
|
||||
}
|
||||
return nil
|
||||
|
@ -657,16 +654,16 @@ func (e *exportContext) addRelationOptions(relationKey string) error {
|
|||
|
||||
func (e *exportContext) getRelationOptions(relationKey string) ([]database.Record, error) {
|
||||
relationOptionsDetails, err := e.objectStore.SpaceIndex(e.spaceId).Query(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
RelationKey: bundle.RelationKeyLayout.String(),
|
||||
RelationKey: bundle.RelationKeyLayout,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Int64(int64(model.ObjectType_relationOption)),
|
||||
Value: domain.Int64(model.ObjectType_relationOption),
|
||||
},
|
||||
{
|
||||
RelationKey: bundle.RelationKeyRelationKey.String(),
|
||||
RelationKey: bundle.RelationKeyRelationKey,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(relationKey),
|
||||
Value: domain.String(relationKey),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -677,7 +674,7 @@ func (e *exportContext) getRelationOptions(relationKey string) ([]database.Recor
|
|||
}
|
||||
|
||||
func (e *exportContext) processObjectTypesAndSetOfList(objectTypes, setOfList []string) error {
|
||||
objectDetails, err := e.queryAndFilterObjectsByRelation(e.spaceId, lo.Union(objectTypes, setOfList), bundle.RelationKeyId.String())
|
||||
objectDetails, err := e.queryAndFilterObjectsByRelation(e.spaceId, lo.Union(objectTypes, setOfList), bundle.RelationKeyId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -698,12 +695,12 @@ func (e *exportContext) processObjectTypesAndSetOfList(objectTypes, setOfList []
|
|||
func (e *exportContext) addObjectsAndCollectRecommendedRelations(objectTypes []database.Record) ([]string, error) {
|
||||
recommendedRelations := make([]string, 0, len(objectTypes))
|
||||
for i := 0; i < len(objectTypes); i++ {
|
||||
rawUniqueKey := pbtypes.GetString(objectTypes[i].Details, bundle.RelationKeyUniqueKey.String())
|
||||
rawUniqueKey := objectTypes[i].Details.GetString(bundle.RelationKeyUniqueKey)
|
||||
uniqueKey, err := domain.UnmarshalUniqueKey(rawUniqueKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
id := pbtypes.GetString(objectTypes[i].Details, bundle.RelationKeyId.String())
|
||||
id := objectTypes[i].Details.GetString(bundle.RelationKeyId)
|
||||
e.docs[id] = objectTypes[i].Details
|
||||
if uniqueKey.SmartblockType() == smartblock.SmartBlockTypeObjectType {
|
||||
key, err := domain.GetTypeKeyFromRawUniqueKey(rawUniqueKey)
|
||||
|
@ -713,24 +710,24 @@ func (e *exportContext) addObjectsAndCollectRecommendedRelations(objectTypes []d
|
|||
if bundle.IsInternalType(key) {
|
||||
continue
|
||||
}
|
||||
recommendedRelations = append(recommendedRelations, pbtypes.GetStringList(objectTypes[i].Details, bundle.RelationKeyRecommendedRelations.String())...)
|
||||
recommendedRelations = append(recommendedRelations, objectTypes[i].Details.GetStringList(bundle.RelationKeyRecommendedRelations)...)
|
||||
}
|
||||
}
|
||||
return recommendedRelations, nil
|
||||
}
|
||||
|
||||
func (e *exportContext) addRecommendedRelations(recommendedRelations []string) error {
|
||||
relations, err := e.queryAndFilterObjectsByRelation(e.spaceId, recommendedRelations, bundle.RelationKeyId.String())
|
||||
relations, err := e.queryAndFilterObjectsByRelation(e.spaceId, recommendedRelations, bundle.RelationKeyId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, relation := range relations {
|
||||
id := pbtypes.GetString(relation.Details, bundle.RelationKeyId.String())
|
||||
id := relation.Details.GetString(bundle.RelationKeyId)
|
||||
if id == addr.MissingObject {
|
||||
continue
|
||||
}
|
||||
|
||||
relationKey := pbtypes.GetString(relation.Details, bundle.RelationKeyUniqueKey.String())
|
||||
relationKey := relation.Details.GetString(bundle.RelationKeyUniqueKey)
|
||||
uniqueKey, err := domain.UnmarshalUniqueKey(relationKey)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -744,7 +741,7 @@ func (e *exportContext) addRecommendedRelations(recommendedRelations []string) e
|
|||
}
|
||||
|
||||
func (e *exportContext) addNestedObjects(ids []string) error {
|
||||
nestedDocs := make(map[string]*types.Struct, 0)
|
||||
nestedDocs := make(map[string]*domain.Details, 0)
|
||||
for _, id := range ids {
|
||||
e.addNestedObject(id, nestedDocs)
|
||||
}
|
||||
|
@ -766,7 +763,7 @@ func (e *exportContext) addNestedObjects(ids []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (e *exportContext) addNestedObject(id string, nestedDocs map[string]*types.Struct) {
|
||||
func (e *exportContext) addNestedObject(id string, nestedDocs map[string]*domain.Details) {
|
||||
links, err := e.objectStore.SpaceIndex(e.spaceId).GetOutboundLinksById(id)
|
||||
if err != nil {
|
||||
log.Errorf("export failed to get outbound links for id: %s", err)
|
||||
|
@ -802,11 +799,11 @@ func (e *exportContext) fillLinkedFiles(id string) ([]string, error) {
|
|||
err := cache.Do(e.picker, id, func(b sb.SmartBlock) error {
|
||||
b.NewState().IterateLinkedFiles(func(fileObjectId string) {
|
||||
res, err := spaceIndex.Query(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
RelationKey: bundle.RelationKeyId.String(),
|
||||
RelationKey: bundle.RelationKeyId,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(fileObjectId),
|
||||
Value: domain.String(fileObjectId),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -841,11 +838,11 @@ func (e *exportContext) getExistedObjects(isProtobuf bool) error {
|
|||
}
|
||||
res = append(res, archivedObjects...)
|
||||
}
|
||||
e.docs = make(map[string]*types.Struct, len(res))
|
||||
e.docs = make(map[string]*domain.Details, len(res))
|
||||
for _, info := range res {
|
||||
objectSpaceID := e.spaceId
|
||||
if objectSpaceID == "" {
|
||||
objectSpaceID = pbtypes.GetString(info.Details, bundle.RelationKeySpaceId.String())
|
||||
objectSpaceID = info.Details.GetString(bundle.RelationKeySpaceId)
|
||||
}
|
||||
sbType, err := e.sbtProvider.Type(objectSpaceID, info.Id)
|
||||
if err != nil {
|
||||
|
@ -863,7 +860,7 @@ func (e *exportContext) getExistedObjects(isProtobuf bool) error {
|
|||
|
||||
func (e *exportContext) listTargetTypesFromTemplates(ids []string) []string {
|
||||
for id, object := range e.docs {
|
||||
if pbtypes.Get(object, bundle.RelationKeyTargetObjectType.String()) != nil {
|
||||
if object.Has(bundle.RelationKeyTargetObjectType) {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
|
@ -881,7 +878,7 @@ func (e *exportContext) writeMultiDoc(ctx context.Context, mw converter.MultiCon
|
|||
if err != nil {
|
||||
return fmt.Errorf("save file: %w", err)
|
||||
}
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySource, pbtypes.String(fileName))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySource, domain.String(fileName))
|
||||
}
|
||||
if err = mw.Add(b.Space(), st); err != nil {
|
||||
return err
|
||||
|
@ -909,7 +906,7 @@ func (e *exportContext) writeMultiDoc(ctx context.Context, mw converter.MultiCon
|
|||
func (e *exportContext) writeDoc(ctx context.Context, wr writer, docId string) (err error) {
|
||||
return cache.Do(e.picker, docId, func(b sb.SmartBlock) error {
|
||||
st := b.NewState()
|
||||
if pbtypes.GetBool(st.CombinedDetails(), bundle.RelationKeyIsDeleted.String()) {
|
||||
if st.CombinedDetails().GetBool(bundle.RelationKeyIsDeleted) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -918,7 +915,7 @@ func (e *exportContext) writeDoc(ctx context.Context, wr writer, docId string) (
|
|||
if err != nil {
|
||||
return fmt.Errorf("save file: %w", err)
|
||||
}
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySource, pbtypes.String(fileName))
|
||||
st.SetDetailAndBundledRelation(bundle.RelationKeySource, domain.String(fileName))
|
||||
// Don't save file objects in markdown
|
||||
if e.format == model.Export_Markdown {
|
||||
return nil
|
||||
|
@ -944,7 +941,7 @@ func (e *exportContext) writeDoc(ctx context.Context, wr writer, docId string) (
|
|||
} else {
|
||||
filename = makeFileName(docId, e.spaceId, conv.Ext(), st, b.Type())
|
||||
}
|
||||
lastModifiedDate := pbtypes.GetInt64(st.LocalDetails(), bundle.RelationKeyLastModifiedDate.String())
|
||||
lastModifiedDate := st.LocalDetails().GetInt64(bundle.RelationKeyLastModifiedDate)
|
||||
if err = wr.WriteFile(filename, bytes.NewReader(result), lastModifiedDate); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -955,7 +952,7 @@ func (e *exportContext) writeDoc(ctx context.Context, wr writer, docId string) (
|
|||
func (e *exportContext) saveFile(ctx context.Context, wr writer, fileObject sb.SmartBlock, exportAllSpaces bool) (fileName string, err error) {
|
||||
fullId := domain.FullFileId{
|
||||
SpaceId: fileObject.Space().Id(),
|
||||
FileId: domain.FileId(pbtypes.GetString(fileObject.Details(), bundle.RelationKeyFileId.String())),
|
||||
FileId: domain.FileId(fileObject.Details().GetString(bundle.RelationKeyFileId)),
|
||||
}
|
||||
|
||||
file, err := e.fileService.FileByHash(ctx, fullId)
|
||||
|
@ -997,7 +994,7 @@ func (e *exportContext) createProfileFile(spaceID string, wr writer) error {
|
|||
return err
|
||||
}
|
||||
err = cache.Do(e.picker, spc.DerivedIDs().Workspace, func(b sb.SmartBlock) error {
|
||||
spaceDashBoardID = pbtypes.GetString(b.CombinedDetails(), bundle.RelationKeySpaceDashboardId.String())
|
||||
spaceDashBoardID = b.CombinedDetails().GetString(bundle.RelationKeySpaceDashboardId)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -1022,14 +1019,14 @@ func (e *exportContext) createProfileFile(spaceID string, wr writer) error {
|
|||
}
|
||||
|
||||
func makeMarkdownName(s *state.State, wr writer, docID, ext, spaceId string) string {
|
||||
name := pbtypes.GetString(s.Details(), bundle.RelationKeyName.String())
|
||||
name := s.Details().GetString(bundle.RelationKeyName)
|
||||
if name == "" {
|
||||
name = s.Snippet()
|
||||
}
|
||||
path := ""
|
||||
// space can be empty in case user want to export all spaces
|
||||
if spaceId == "" {
|
||||
spaceId := pbtypes.GetString(s.LocalDetails(), bundle.RelationKeySpaceId.String())
|
||||
spaceId := s.LocalDetails().GetString(bundle.RelationKeySpaceId)
|
||||
path = filepath.Join(spaceDirectory, spaceId)
|
||||
}
|
||||
return wr.Namer().Get(path, docID, name, ext)
|
||||
|
@ -1040,7 +1037,7 @@ func makeFileName(docId, spaceId, ext string, st *state.State, blockType smartbl
|
|||
filename := filepath.Join(dir, docId+ext)
|
||||
// space can be empty in case user want to export all spaces
|
||||
if spaceId == "" {
|
||||
spaceId := pbtypes.GetString(st.LocalDetails(), bundle.RelationKeySpaceId.String())
|
||||
spaceId := st.LocalDetails().GetString(bundle.RelationKeySpaceId)
|
||||
filename = filepath.Join(spaceDirectory, spaceId, filename)
|
||||
}
|
||||
return filename
|
||||
|
@ -1063,11 +1060,11 @@ func provideFileDirectory(blockType smartblock.SmartBlockType) string {
|
|||
}
|
||||
}
|
||||
|
||||
func objectValid(sbType smartblock.SmartBlockType, info *model.ObjectInfo, includeArchived bool, isProtobuf bool) bool {
|
||||
func objectValid(sbType smartblock.SmartBlockType, info *database.ObjectInfo, includeArchived bool, isProtobuf bool) bool {
|
||||
if info.Id == addr.AnytypeProfileId {
|
||||
return false
|
||||
}
|
||||
if !isProtobuf && !validTypeForNonProtobuf(sbType) && !validLayoutForNonProtobuf(info.Details) {
|
||||
if !isProtobuf && (!validTypeForNonProtobuf(sbType) || !validLayoutForNonProtobuf(info.Details)) {
|
||||
return false
|
||||
}
|
||||
if isProtobuf && !validType(sbType) {
|
||||
|
@ -1076,7 +1073,7 @@ func objectValid(sbType smartblock.SmartBlockType, info *model.ObjectInfo, inclu
|
|||
if strings.HasPrefix(info.Id, addr.BundledObjectTypeURLPrefix) || strings.HasPrefix(info.Id, addr.BundledRelationURLPrefix) {
|
||||
return false
|
||||
}
|
||||
if pbtypes.GetBool(info.Details, bundle.RelationKeyIsArchived.String()) && !includeArchived {
|
||||
if info.Details.GetBool(bundle.RelationKeyIsArchived) && !includeArchived {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
@ -1123,10 +1120,8 @@ func (fn *namer) Get(path, hash, title, ext string) (name string) {
|
|||
}
|
||||
|
||||
func validType(sbType smartblock.SmartBlockType) bool {
|
||||
return sbType == smartblock.SmartBlockTypeHome ||
|
||||
sbType == smartblock.SmartBlockTypeProfilePage ||
|
||||
return sbType == smartblock.SmartBlockTypeProfilePage ||
|
||||
sbType == smartblock.SmartBlockTypePage ||
|
||||
sbType == smartblock.SmartBlockTypeSubObject ||
|
||||
sbType == smartblock.SmartBlockTypeTemplate ||
|
||||
sbType == smartblock.SmartBlockTypeWorkspace ||
|
||||
sbType == smartblock.SmartBlockTypeWidget ||
|
||||
|
@ -1143,9 +1138,9 @@ func validTypeForNonProtobuf(sbType smartblock.SmartBlockType) bool {
|
|||
sbType == smartblock.SmartBlockTypeFileObject
|
||||
}
|
||||
|
||||
func validLayoutForNonProtobuf(details *types.Struct) bool {
|
||||
return pbtypes.GetFloat64(details, bundle.RelationKeyLayout.String()) != float64(model.ObjectType_collection) &&
|
||||
pbtypes.GetFloat64(details, bundle.RelationKeyLayout.String()) != float64(model.ObjectType_set)
|
||||
func validLayoutForNonProtobuf(details *domain.Details) bool {
|
||||
return details.GetInt64(bundle.RelationKeyLayout) != int64(model.ObjectType_collection) &&
|
||||
details.GetInt64(bundle.RelationKeyLayout) != int64(model.ObjectType_set)
|
||||
}
|
||||
|
||||
func cleanupFile(wr writer) {
|
||||
|
@ -1153,7 +1148,7 @@ func cleanupFile(wr writer) {
|
|||
os.Remove(wr.Path())
|
||||
}
|
||||
|
||||
func listObjectIds(docs map[string]*types.Struct) []string {
|
||||
func listObjectIds(docs map[string]*domain.Details) []string {
|
||||
ids := make([]string, 0, len(docs))
|
||||
for id := range docs {
|
||||
ids = append(ids, id)
|
||||
|
@ -1162,5 +1157,5 @@ func listObjectIds(docs map[string]*types.Struct) []string {
|
|||
}
|
||||
|
||||
func isLinkedObjectExist(rec []database.Record) bool {
|
||||
return len(rec) > 0 && !pbtypes.GetBool(rec[0].Details, bundle.RelationKeyIsDeleted.String())
|
||||
return len(rec) > 0 && !rec[0].Details.GetBool(bundle.RelationKeyIsDeleted)
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,6 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/collection"
|
||||
|
@ -12,11 +11,11 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/editor/template"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
simpleDataview "github.com/anyproto/anytype-heart/core/block/simple/dataview"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
sb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
type ImportCollectionSetting struct {
|
||||
|
@ -73,7 +72,7 @@ func (r *ImportCollection) MakeImportCollection(req *ImportCollectionSetting) (*
|
|||
}
|
||||
}
|
||||
|
||||
detailsStruct = pbtypes.StructMerge(st.CombinedDetails(), detailsStruct, false)
|
||||
detailsStruct = st.CombinedDetails().Merge(detailsStruct)
|
||||
st.UpdateStoreSlice(template.CollectionStoreKey, req.targetObjects)
|
||||
|
||||
return r.getRootCollectionSnapshot(req.collectionName, st, detailsStruct, req.fileKeys), nil
|
||||
|
@ -82,19 +81,19 @@ func (r *ImportCollection) MakeImportCollection(req *ImportCollectionSetting) (*
|
|||
func (r *ImportCollection) getRootCollectionSnapshot(
|
||||
collectionName string,
|
||||
st *state.State,
|
||||
detailsStruct *types.Struct,
|
||||
detailsStruct *domain.Details,
|
||||
fileKeys []*pb.ChangeFileKeys,
|
||||
) *Snapshot {
|
||||
if detailsStruct.GetFields() == nil {
|
||||
detailsStruct = &types.Struct{Fields: map[string]*types.Value{}}
|
||||
if detailsStruct == nil {
|
||||
detailsStruct = domain.NewDetails()
|
||||
}
|
||||
detailsStruct.Fields[bundle.RelationKeyLayout.String()] = pbtypes.Int64(int64(model.ObjectType_collection))
|
||||
detailsStruct.SetInt64(bundle.RelationKeyLayout, int64(model.ObjectType_collection))
|
||||
return &Snapshot{
|
||||
Id: uuid.New().String(),
|
||||
FileName: collectionName,
|
||||
SbType: sb.SmartBlockTypePage,
|
||||
Snapshot: &pb.ChangeSnapshot{
|
||||
Data: &model.SmartBlockSnapshotBase{
|
||||
Snapshot: &SnapshotModel{
|
||||
SbType: sb.SmartBlockTypePage,
|
||||
Data: &StateSnapshot{
|
||||
Blocks: st.Blocks(),
|
||||
Details: detailsStruct,
|
||||
ObjectTypes: []string{bundle.TypeKeyCollection.String()},
|
||||
|
@ -125,16 +124,14 @@ func (r *ImportCollection) addRelations(st *state.State) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *ImportCollection) getCreateCollectionRequest(collectionName string, icon string, shouldBeFavorite bool) *types.Struct {
|
||||
details := make(map[string]*types.Value, 0)
|
||||
details[bundle.RelationKeySourceFilePath.String()] = pbtypes.String(collectionName)
|
||||
details[bundle.RelationKeyName.String()] = pbtypes.String(collectionName)
|
||||
details[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(shouldBeFavorite)
|
||||
details[bundle.RelationKeyLayout.String()] = pbtypes.Float64(float64(model.ObjectType_collection))
|
||||
details[bundle.RelationKeyIconImage.String()] = pbtypes.String(icon)
|
||||
|
||||
detailsStruct := &types.Struct{Fields: details}
|
||||
return detailsStruct
|
||||
func (r *ImportCollection) getCreateCollectionRequest(collectionName string, icon string, shouldBeFavorite bool) *domain.Details {
|
||||
return domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeySourceFilePath: domain.String(collectionName),
|
||||
bundle.RelationKeyName: domain.String(collectionName),
|
||||
bundle.RelationKeyIsFavorite: domain.Bool(shouldBeFavorite),
|
||||
bundle.RelationKeyLayout: domain.Int64(model.ObjectType_collection),
|
||||
bundle.RelationKeyIconImage: domain.String(icon),
|
||||
})
|
||||
}
|
||||
|
||||
func ReplaceRelationsInDataView(st *state.State, rel *model.RelationLink) error {
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/state"
|
||||
|
@ -20,6 +19,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/simple/file"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/link"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple/text"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/addr"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/logging"
|
||||
|
@ -32,7 +32,7 @@ var randomIcons = []string{"📓", "📕", "📗", "📘", "📙", "📖", "📔
|
|||
|
||||
var log = logging.Logger("import")
|
||||
|
||||
func GetCommonDetails(sourcePath, name, emoji string, layout model.ObjectTypeLayout) *types.Struct {
|
||||
func GetCommonDetails(sourcePath, name, emoji string, layout model.ObjectTypeLayout) *domain.Details {
|
||||
creationTime, modTime := filetime.ExtractFileTimes(sourcePath)
|
||||
if name == "" {
|
||||
name = strings.TrimSuffix(filepath.Base(sourcePath), filepath.Ext(sourcePath))
|
||||
|
@ -42,15 +42,14 @@ func GetCommonDetails(sourcePath, name, emoji string, layout model.ObjectTypeLay
|
|||
}
|
||||
h := sha256.Sum256([]byte(sourcePath))
|
||||
hash := hex.EncodeToString(h[:])
|
||||
fields := map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String(name),
|
||||
bundle.RelationKeySourceFilePath.String(): pbtypes.String(hash),
|
||||
bundle.RelationKeyIconEmoji.String(): pbtypes.String(emoji),
|
||||
bundle.RelationKeyCreatedDate.String(): pbtypes.Int64(creationTime),
|
||||
bundle.RelationKeyLastModifiedDate.String(): pbtypes.Int64(modTime),
|
||||
bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(layout)),
|
||||
}
|
||||
return &types.Struct{Fields: fields}
|
||||
details := domain.NewDetails()
|
||||
details.SetString(bundle.RelationKeyName, name)
|
||||
details.SetString(bundle.RelationKeySourceFilePath, hash)
|
||||
details.SetString(bundle.RelationKeyIconEmoji, emoji)
|
||||
details.SetInt64(bundle.RelationKeyCreatedDate, creationTime)
|
||||
details.SetInt64(bundle.RelationKeyLastModifiedDate, modTime)
|
||||
details.SetInt64(bundle.RelationKeyLayout, int64(layout))
|
||||
return details
|
||||
}
|
||||
|
||||
func UpdateLinksToObjects(st *state.State, oldIDtoNew map[string]string) error {
|
||||
|
@ -217,7 +216,7 @@ func isBundledObjects(targetObjectID string) bool {
|
|||
return true
|
||||
}
|
||||
rel, err := pbtypes.RelationIdToKey(targetObjectID)
|
||||
if err == nil && bundle.HasRelation(rel) {
|
||||
if err == nil && bundle.HasRelation(domain.RelationKey(rel)) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -259,8 +258,8 @@ func handleTextBlock(oldIDtoNew map[string]string, block simple.Block, st *state
|
|||
|
||||
func UpdateObjectIDsInRelations(st *state.State, oldIDtoNew map[string]string) {
|
||||
rels := st.GetRelationLinks()
|
||||
for k, v := range st.Details().GetFields() {
|
||||
relLink := rels.Get(k)
|
||||
for k, v := range st.Details().Iterate() {
|
||||
relLink := rels.Get(string(k))
|
||||
if relLink == nil {
|
||||
continue
|
||||
}
|
||||
|
@ -285,18 +284,17 @@ func isLinkToObject(relLink *model.RelationLink) bool {
|
|||
relLink.Format == model.RelationFormat_file
|
||||
}
|
||||
|
||||
func handleObjectRelation(st *state.State, oldIDtoNew map[string]string, v *types.Value, k string) {
|
||||
if _, ok := v.GetKind().(*types.Value_StringValue); ok {
|
||||
objectsID := v.GetStringValue()
|
||||
newObjectIDs := getNewObjectsIDForRelation([]string{objectsID}, oldIDtoNew)
|
||||
func handleObjectRelation(st *state.State, oldIDtoNew map[string]string, v domain.Value, k domain.RelationKey) {
|
||||
if objectId, ok := v.TryString(); ok {
|
||||
newObjectIDs := getNewObjectsIDForRelation([]string{objectId}, oldIDtoNew)
|
||||
if len(newObjectIDs) != 0 {
|
||||
st.SetDetail(k, pbtypes.String(newObjectIDs[0]))
|
||||
st.SetDetail(k, domain.String(newObjectIDs[0]))
|
||||
}
|
||||
return
|
||||
}
|
||||
objectsIDs := pbtypes.GetStringListValue(v)
|
||||
objectsIDs := v.StringList()
|
||||
objectsIDs = getNewObjectsIDForRelation(objectsIDs, oldIDtoNew)
|
||||
st.SetDetail(k, pbtypes.StringList(objectsIDs))
|
||||
st.SetDetail(k, domain.StringList(objectsIDs))
|
||||
}
|
||||
|
||||
func getNewObjectsIDForRelation(objectsIDs []string, oldIDtoNew map[string]string) []string {
|
||||
|
|
|
@ -4,11 +4,11 @@ package mock_objectcreator
|
|||
|
||||
import (
|
||||
common "github.com/anyproto/anytype-heart/core/block/import/common"
|
||||
domain "github.com/anyproto/anytype-heart/core/domain"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
objectcreator "github.com/anyproto/anytype-heart/core/block/import/common/objectcreator"
|
||||
|
||||
types "github.com/gogo/protobuf/types"
|
||||
)
|
||||
|
||||
// MockService is an autogenerated mock type for the Service type
|
||||
|
@ -25,24 +25,24 @@ func (_m *MockService) EXPECT() *MockService_Expecter {
|
|||
}
|
||||
|
||||
// Create provides a mock function with given fields: dataObject, sn
|
||||
func (_m *MockService) Create(dataObject *objectcreator.DataObject, sn *common.Snapshot) (*types.Struct, string, error) {
|
||||
func (_m *MockService) Create(dataObject *objectcreator.DataObject, sn *common.Snapshot) (*domain.Details, string, error) {
|
||||
ret := _m.Called(dataObject, sn)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Create")
|
||||
}
|
||||
|
||||
var r0 *types.Struct
|
||||
var r0 *domain.Details
|
||||
var r1 string
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(*objectcreator.DataObject, *common.Snapshot) (*types.Struct, string, error)); ok {
|
||||
if rf, ok := ret.Get(0).(func(*objectcreator.DataObject, *common.Snapshot) (*domain.Details, string, error)); ok {
|
||||
return rf(dataObject, sn)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(*objectcreator.DataObject, *common.Snapshot) *types.Struct); ok {
|
||||
if rf, ok := ret.Get(0).(func(*objectcreator.DataObject, *common.Snapshot) *domain.Details); ok {
|
||||
r0 = rf(dataObject, sn)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.Struct)
|
||||
r0 = ret.Get(0).(*domain.Details)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,12 +80,12 @@ func (_c *MockService_Create_Call) Run(run func(dataObject *objectcreator.DataOb
|
|||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockService_Create_Call) Return(_a0 *types.Struct, _a1 string, _a2 error) *MockService_Create_Call {
|
||||
func (_c *MockService_Create_Call) Return(_a0 *domain.Details, _a1 string, _a2 error) *MockService_Create_Call {
|
||||
_c.Call.Return(_a0, _a1, _a2)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockService_Create_Call) RunAndReturn(run func(*objectcreator.DataObject, *common.Snapshot) (*types.Struct, string, error)) *MockService_Create_Call {
|
||||
func (_c *MockService_Create_Call) RunAndReturn(run func(*objectcreator.DataObject, *common.Snapshot) (*domain.Details, string, error)) *MockService_Create_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/samber/lo"
|
||||
"go.uber.org/zap"
|
||||
|
||||
|
@ -41,7 +40,7 @@ var log = logging.Logger("import")
|
|||
// Service encapsulate logic with creation of given smartblocks
|
||||
type Service interface {
|
||||
//nolint:lll
|
||||
Create(dataObject *DataObject, sn *common.Snapshot) (*types.Struct, string, error)
|
||||
Create(dataObject *DataObject, sn *common.Snapshot) (*domain.Details, string, error)
|
||||
}
|
||||
|
||||
type ObjectGetterDeleter interface {
|
||||
|
@ -79,7 +78,7 @@ func New(detailsService detailservice.Service,
|
|||
}
|
||||
|
||||
// Create creates smart blocks from given snapshots
|
||||
func (oc *ObjectCreator) Create(dataObject *DataObject, sn *common.Snapshot) (*types.Struct, string, error) {
|
||||
func (oc *ObjectCreator) Create(dataObject *DataObject, sn *common.Snapshot) (*domain.Details, string, error) {
|
||||
snapshot := sn.Snapshot.Data
|
||||
oldIDtoNew := dataObject.oldIDtoNew
|
||||
ctx := dataObject.ctx
|
||||
|
@ -88,15 +87,15 @@ func (oc *ObjectCreator) Create(dataObject *DataObject, sn *common.Snapshot) (*t
|
|||
|
||||
newID := oldIDtoNew[sn.Id]
|
||||
|
||||
if sn.SbType == coresb.SmartBlockTypeFile {
|
||||
if sn.Snapshot.SbType == coresb.SmartBlockTypeFile {
|
||||
return nil, newID, nil
|
||||
}
|
||||
|
||||
oc.setRootBlock(snapshot, newID)
|
||||
|
||||
oc.injectImportDetails(sn, origin)
|
||||
st := state.NewDocFromSnapshot(newID, sn.Snapshot, state.WithUniqueKeyMigration(sn.SbType)).(*state.State)
|
||||
st.SetLocalDetail(bundle.RelationKeyLastModifiedDate.String(), pbtypes.Int64(pbtypes.GetInt64(snapshot.Details, bundle.RelationKeyLastModifiedDate.String())))
|
||||
st := state.NewDocFromSnapshot(newID, sn.Snapshot.ToProto()).(*state.State)
|
||||
st.SetLocalDetail(bundle.RelationKeyLastModifiedDate, snapshot.Details.Get(bundle.RelationKeyLastModifiedDate))
|
||||
|
||||
var (
|
||||
filesToDelete []string
|
||||
|
@ -114,12 +113,12 @@ func (oc *ObjectCreator) Create(dataObject *DataObject, sn *common.Snapshot) (*t
|
|||
}
|
||||
|
||||
oc.updateKeys(st, oldIDtoNew)
|
||||
if sn.SbType == coresb.SmartBlockTypeWorkspace {
|
||||
if sn.Snapshot.SbType == coresb.SmartBlockTypeWorkspace {
|
||||
oc.setSpaceDashboardID(spaceID, st)
|
||||
return nil, newID, nil
|
||||
}
|
||||
|
||||
if sn.SbType == coresb.SmartBlockTypeWidget {
|
||||
if sn.Snapshot.SbType == coresb.SmartBlockTypeWidget {
|
||||
return oc.updateWidgetObject(st)
|
||||
}
|
||||
|
||||
|
@ -132,7 +131,7 @@ func (oc *ObjectCreator) Create(dataObject *DataObject, sn *common.Snapshot) (*t
|
|||
})
|
||||
|
||||
typeKeys := st.ObjectTypeKeys()
|
||||
if sn.SbType == coresb.SmartBlockTypeObjectType {
|
||||
if sn.Snapshot.SbType == coresb.SmartBlockTypeObjectType {
|
||||
// we widen typeKeys here to install bundled templates for imported object type
|
||||
typeKeys = append(typeKeys, domain.TypeKey(st.UniqueKeyInternal()))
|
||||
}
|
||||
|
@ -140,7 +139,7 @@ func (oc *ObjectCreator) Create(dataObject *DataObject, sn *common.Snapshot) (*t
|
|||
if err != nil {
|
||||
log.With("objectID", newID).Errorf("failed to install bundled relations and types: %s", err)
|
||||
}
|
||||
var respDetails *types.Struct
|
||||
var respDetails *domain.Details
|
||||
if payload := dataObject.createPayloads[newID]; payload.RootRawChange != nil {
|
||||
respDetails, err = oc.createNewObject(ctx, spaceID, payload, st, newID, oldIDtoNew)
|
||||
if err != nil {
|
||||
|
@ -148,7 +147,7 @@ func (oc *ObjectCreator) Create(dataObject *DataObject, sn *common.Snapshot) (*t
|
|||
return nil, "", err
|
||||
}
|
||||
} else {
|
||||
if canUpdateObject(sn.SbType) {
|
||||
if canUpdateObject(sn.Snapshot.SbType) {
|
||||
respDetails = oc.updateExistingObject(st, oldIDtoNew, newID)
|
||||
}
|
||||
}
|
||||
|
@ -174,11 +173,11 @@ func canUpdateObject(sbType coresb.SmartBlockType) bool {
|
|||
}
|
||||
|
||||
func (oc *ObjectCreator) injectImportDetails(sn *common.Snapshot, origin objectorigin.ObjectOrigin) {
|
||||
lastModifiedDate := pbtypes.GetInt64(sn.Snapshot.Data.Details, bundle.RelationKeyLastModifiedDate.String())
|
||||
createdDate := pbtypes.GetInt64(sn.Snapshot.Data.Details, bundle.RelationKeyCreatedDate.String())
|
||||
lastModifiedDate := sn.Snapshot.Data.Details.GetInt64(bundle.RelationKeyLastModifiedDate)
|
||||
createdDate := sn.Snapshot.Data.Details.GetInt64(bundle.RelationKeyCreatedDate)
|
||||
if lastModifiedDate == 0 {
|
||||
if createdDate != 0 {
|
||||
sn.Snapshot.Data.Details.Fields[bundle.RelationKeyLastModifiedDate.String()] = pbtypes.Int64(int64(createdDate))
|
||||
sn.Snapshot.Data.Details.SetInt64(bundle.RelationKeyLastModifiedDate, createdDate)
|
||||
} else {
|
||||
// we can't fallback to time.Now() because it will be inconsistent with the time used in object tree header.
|
||||
// So instead we should EXPLICITLY set creation date to the snapshot in all importers
|
||||
|
@ -191,12 +190,12 @@ func (oc *ObjectCreator) injectImportDetails(sn *common.Snapshot, origin objecto
|
|||
sn.Snapshot.Data.OriginalCreatedTimestamp = createdDate
|
||||
}
|
||||
|
||||
sn.Snapshot.Data.Details.Fields[bundle.RelationKeyOrigin.String()] = pbtypes.Int64(int64(origin.Origin))
|
||||
sn.Snapshot.Data.Details.Fields[bundle.RelationKeyImportType.String()] = pbtypes.Int64(int64(origin.ImportType))
|
||||
sn.Snapshot.Data.Details.SetInt64(bundle.RelationKeyOrigin, int64(origin.Origin))
|
||||
sn.Snapshot.Data.Details.SetInt64(bundle.RelationKeyImportType, int64(origin.ImportType))
|
||||
// we don't need to inject relatonLinks, they will be automatically injected for bundled relations
|
||||
}
|
||||
|
||||
func (oc *ObjectCreator) updateExistingObject(st *state.State, oldIDtoNew map[string]string, newID string) *types.Struct {
|
||||
func (oc *ObjectCreator) updateExistingObject(st *state.State, oldIDtoNew map[string]string, newID string) *domain.Details {
|
||||
if st.Store() != nil {
|
||||
oc.updateLinksInCollections(st, oldIDtoNew, false)
|
||||
}
|
||||
|
@ -214,7 +213,7 @@ func (oc *ObjectCreator) installBundledRelationsAndTypes(
|
|||
idsToCheck := make([]string, 0, len(links)+len(objectTypeKeys))
|
||||
for _, link := range links {
|
||||
// TODO: check if we have them in oldIDtoNew
|
||||
if !bundle.HasRelation(link.Key) {
|
||||
if !bundle.HasRelation(domain.RelationKey(link.Key)) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -243,8 +242,8 @@ func (oc *ObjectCreator) createNewObject(
|
|||
payload treestorage.TreeStorageCreatePayload,
|
||||
st *state.State,
|
||||
newID string,
|
||||
oldIDtoNew map[string]string) (*types.Struct, error) {
|
||||
var respDetails *types.Struct
|
||||
oldIDtoNew map[string]string) (*domain.Details, error) {
|
||||
var respDetails *domain.Details
|
||||
spc, err := oc.spaceService.Get(ctx, spaceID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get space %s: %w", spaceID, err)
|
||||
|
@ -282,7 +281,7 @@ func (oc *ObjectCreator) createNewObject(
|
|||
return respDetails, nil
|
||||
}
|
||||
|
||||
func (oc *ObjectCreator) setRootBlock(snapshot *model.SmartBlockSnapshotBase, newID string) {
|
||||
func (oc *ObjectCreator) setRootBlock(snapshot *common.StateSnapshot, newID string) {
|
||||
var found bool
|
||||
for _, b := range snapshot.Blocks {
|
||||
if b.Id == newID {
|
||||
|
@ -323,28 +322,28 @@ func (oc *ObjectCreator) deleteFile(spaceId string, hash string) {
|
|||
|
||||
func (oc *ObjectCreator) setSpaceDashboardID(spaceID string, st *state.State) {
|
||||
// hand-pick relation because space is a special case
|
||||
var details []*model.Detail
|
||||
spaceDashBoardID := pbtypes.GetString(st.CombinedDetails(), bundle.RelationKeySpaceDashboardId.String())
|
||||
if spaceDashBoardID != "" {
|
||||
details = append(details, &model.Detail{
|
||||
Key: bundle.RelationKeySpaceDashboardId.String(),
|
||||
Value: pbtypes.String(spaceDashBoardID),
|
||||
var details []domain.Detail
|
||||
ids := st.CombinedDetails().GetStringList(bundle.RelationKeySpaceDashboardId)
|
||||
if len(ids) > 0 {
|
||||
details = append(details, domain.Detail{
|
||||
Key: bundle.RelationKeySpaceDashboardId,
|
||||
Value: domain.StringList(ids),
|
||||
})
|
||||
}
|
||||
|
||||
spaceName := pbtypes.GetString(st.CombinedDetails(), bundle.RelationKeyName.String())
|
||||
spaceName := st.CombinedDetails().GetString(bundle.RelationKeyName)
|
||||
if spaceName != "" {
|
||||
details = append(details, &model.Detail{
|
||||
Key: bundle.RelationKeyName.String(),
|
||||
Value: pbtypes.String(spaceName),
|
||||
details = append(details, domain.Detail{
|
||||
Key: bundle.RelationKeyName,
|
||||
Value: domain.String(spaceName),
|
||||
})
|
||||
}
|
||||
|
||||
iconOption := pbtypes.GetInt64(st.CombinedDetails(), bundle.RelationKeyIconOption.String())
|
||||
iconOption := st.CombinedDetails().GetInt64(bundle.RelationKeyIconOption)
|
||||
if iconOption != 0 {
|
||||
details = append(details, &model.Detail{
|
||||
Key: bundle.RelationKeyIconOption.String(),
|
||||
Value: pbtypes.Int64(iconOption),
|
||||
details = append(details, domain.Detail{
|
||||
Key: bundle.RelationKeyIconOption,
|
||||
Value: domain.Int64(iconOption),
|
||||
})
|
||||
}
|
||||
if len(details) > 0 {
|
||||
|
@ -365,8 +364,8 @@ func (oc *ObjectCreator) setSpaceDashboardID(spaceID string, st *state.State) {
|
|||
}
|
||||
}
|
||||
|
||||
func (oc *ObjectCreator) resetState(newID string, st *state.State) *types.Struct {
|
||||
var respDetails *types.Struct
|
||||
func (oc *ObjectCreator) resetState(newID string, st *state.State) *domain.Details {
|
||||
var respDetails *domain.Details
|
||||
err := cache.Do(oc.objectGetterDeleter, newID, func(b smartblock.SmartBlock) error {
|
||||
err := history.ResetToVersion(b, st)
|
||||
if err != nil {
|
||||
|
@ -389,8 +388,8 @@ func (oc *ObjectCreator) resetState(newID string, st *state.State) *types.Struct
|
|||
return respDetails
|
||||
}
|
||||
|
||||
func (oc *ObjectCreator) setFavorite(snapshot *model.SmartBlockSnapshotBase, newID string) {
|
||||
isFavorite := pbtypes.GetBool(snapshot.Details, bundle.RelationKeyIsFavorite.String())
|
||||
func (oc *ObjectCreator) setFavorite(snapshot *common.StateSnapshot, newID string) {
|
||||
isFavorite := snapshot.Details.GetBool(bundle.RelationKeyIsFavorite)
|
||||
if isFavorite {
|
||||
err := oc.detailsService.SetIsFavorite(newID, true, false)
|
||||
if err != nil {
|
||||
|
@ -399,8 +398,8 @@ func (oc *ObjectCreator) setFavorite(snapshot *model.SmartBlockSnapshotBase, new
|
|||
}
|
||||
}
|
||||
|
||||
func (oc *ObjectCreator) setArchived(snapshot *model.SmartBlockSnapshotBase, newID string) {
|
||||
isArchive := pbtypes.GetBool(snapshot.Details, bundle.RelationKeyIsArchived.String())
|
||||
func (oc *ObjectCreator) setArchived(snapshot *common.StateSnapshot, newID string) {
|
||||
isArchive := snapshot.Details.GetBool(bundle.RelationKeyIsArchived)
|
||||
if isArchive {
|
||||
err := oc.detailsService.SetIsArchived(newID, true)
|
||||
if err != nil {
|
||||
|
@ -472,7 +471,7 @@ func (oc *ObjectCreator) mergeCollections(existedObjects []string, st *state.Sta
|
|||
st.UpdateStoreSlice(template.CollectionStoreKey, result)
|
||||
}
|
||||
|
||||
func (oc *ObjectCreator) updateWidgetObject(st *state.State) (*types.Struct, string, error) {
|
||||
func (oc *ObjectCreator) updateWidgetObject(st *state.State) (*domain.Details, string, error) {
|
||||
err := cache.DoState(oc.objectGetterDeleter, st.RootId(), func(oldState *state.State, sb smartblock.SmartBlock) error {
|
||||
blocks := st.Blocks()
|
||||
blocksMap := make(map[string]*model.Block, len(blocks))
|
||||
|
@ -542,32 +541,31 @@ func (oc *ObjectCreator) getExistingWidgetsTargetIDs(oldState *state.State) (map
|
|||
}
|
||||
|
||||
func (oc *ObjectCreator) updateKeys(st *state.State, oldIDtoNew map[string]string) {
|
||||
for key, value := range st.Details().GetFields() {
|
||||
if newKey, ok := oldIDtoNew[key]; ok && newKey != key {
|
||||
oc.updateDetails(st, newKey, value, key)
|
||||
for key, value := range st.Details().Iterate() {
|
||||
if newKey, ok := oldIDtoNew[string(key)]; ok && newKey != string(key) {
|
||||
oc.updateDetails(st, domain.RelationKey(newKey), value, key)
|
||||
}
|
||||
}
|
||||
|
||||
if newKey, ok := oldIDtoNew[st.ObjectTypeKey().String()]; ok {
|
||||
st.SetObjectTypeKey(domain.TypeKey(newKey))
|
||||
}
|
||||
}
|
||||
|
||||
func (oc *ObjectCreator) updateDetails(st *state.State, newKey string, value *types.Value, key string) {
|
||||
func (oc *ObjectCreator) updateDetails(st *state.State, newKey domain.RelationKey, value domain.Value, key domain.RelationKey) {
|
||||
st.SetDetail(newKey, value)
|
||||
link := oc.findRelationLinkByKey(st, key)
|
||||
if link != nil {
|
||||
link.Key = newKey
|
||||
link.Key = string(newKey)
|
||||
st.AddRelationLinks(link)
|
||||
}
|
||||
st.RemoveRelation(key)
|
||||
}
|
||||
|
||||
func (oc *ObjectCreator) findRelationLinkByKey(st *state.State, key string) *model.RelationLink {
|
||||
func (oc *ObjectCreator) findRelationLinkByKey(st *state.State, key domain.RelationKey) *model.RelationLink {
|
||||
relationLinks := st.GetRelationLinks()
|
||||
var link *model.RelationLink
|
||||
for _, link = range relationLinks {
|
||||
if link.Key == key {
|
||||
if domain.RelationKey(link.Key) == key {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/detailservice/mock_detailservice"
|
||||
|
@ -17,13 +16,11 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/object/objectcreator"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/domain/objectorigin"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace"
|
||||
"github.com/anyproto/anytype-heart/space/mock_space"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func TestObjectCreator_Create(t *testing.T) {
|
||||
|
@ -44,33 +41,32 @@ func TestObjectCreator_Create(t *testing.T) {
|
|||
oldToNew := map[string]string{importedSpaceIdParticipantId: participantId}
|
||||
dataObject := NewDataObject(context.Background(), oldToNew, nil, objectorigin.Import(model.Import_Pb), spaceID)
|
||||
sn := &common.Snapshot{
|
||||
Id: importedSpaceIdParticipantId,
|
||||
SbType: coresb.SmartBlockTypeParticipant,
|
||||
Snapshot: &pb.ChangeSnapshot{
|
||||
Data: &model.SmartBlockSnapshotBase{
|
||||
Details: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyId.String(): pbtypes.String(importedSpaceIdParticipantId),
|
||||
bundle.RelationKeyIdentity.String(): pbtypes.String(identity),
|
||||
bundle.RelationKeySpaceId.String(): pbtypes.String(importedSpaceId),
|
||||
bundle.RelationKeyLastModifiedBy.String(): pbtypes.String(identity),
|
||||
bundle.RelationKeyParticipantPermissions.String(): pbtypes.Int64(int64(model.ParticipantPermissions_Reader)),
|
||||
bundle.RelationKeyParticipantStatus.String(): pbtypes.Int64(int64(model.ParticipantStatus_Active)),
|
||||
},
|
||||
},
|
||||
Id: importedSpaceIdParticipantId,
|
||||
Snapshot: &common.SnapshotModel{
|
||||
SbType: coresb.SmartBlockTypeParticipant,
|
||||
Data: &common.StateSnapshot{
|
||||
Details: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyId: domain.String(importedSpaceIdParticipantId),
|
||||
bundle.RelationKeyIdentity: domain.String(identity),
|
||||
bundle.RelationKeySpaceId: domain.String(importedSpaceId),
|
||||
bundle.RelationKeyLastModifiedBy: domain.String(identity),
|
||||
bundle.RelationKeyParticipantPermissions: domain.Int64(int64(model.ParticipantPermissions_Reader)),
|
||||
bundle.RelationKeyParticipantStatus: domain.Int64(int64(model.ParticipantStatus_Active)),
|
||||
}),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
testParticipant := smarttest.New(participantId)
|
||||
st := testParticipant.NewState()
|
||||
testDetails := &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyId.String(): pbtypes.String(participantId),
|
||||
bundle.RelationKeyIdentity.String(): pbtypes.String(identity),
|
||||
bundle.RelationKeySpaceId.String(): pbtypes.String(spaceID),
|
||||
bundle.RelationKeyLastModifiedBy.String(): pbtypes.String(identity),
|
||||
bundle.RelationKeyParticipantPermissions.String(): pbtypes.Int64(int64(model.ParticipantPermissions_Owner)),
|
||||
bundle.RelationKeyParticipantStatus.String(): pbtypes.Int64(int64(model.ParticipantStatus_Active)),
|
||||
}}
|
||||
testDetails := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyId: domain.String(participantId),
|
||||
bundle.RelationKeyIdentity: domain.String(identity),
|
||||
bundle.RelationKeySpaceId: domain.String(spaceID),
|
||||
bundle.RelationKeyLastModifiedBy: domain.String(identity),
|
||||
bundle.RelationKeyParticipantPermissions: domain.Int64(int64(model.ParticipantPermissions_Owner)),
|
||||
bundle.RelationKeyParticipantStatus: domain.Int64(int64(model.ParticipantStatus_Active)),
|
||||
})
|
||||
st.SetDetails(testDetails)
|
||||
err := testParticipant.Apply(st)
|
||||
assert.Nil(t, err)
|
||||
|
@ -98,9 +94,9 @@ func TestObjectCreator_updateKeys(t *testing.T) {
|
|||
oc := ObjectCreator{}
|
||||
oldToNew := map[string]string{"oldId": "newId", "oldKey": "newKey"}
|
||||
doc := state.NewDoc("oldId", nil).(*state.State)
|
||||
doc.SetDetails(&types.Struct{Fields: map[string]*types.Value{
|
||||
"oldKey": pbtypes.String("test"),
|
||||
}})
|
||||
doc.SetDetails(domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
"oldKey": domain.String("test"),
|
||||
}))
|
||||
doc.AddRelationLinks(&model.RelationLink{
|
||||
Key: "oldKey",
|
||||
})
|
||||
|
@ -108,8 +104,8 @@ func TestObjectCreator_updateKeys(t *testing.T) {
|
|||
oc.updateKeys(doc, oldToNew)
|
||||
|
||||
// then
|
||||
assert.Nil(t, doc.Details().GetFields()["oldKey"])
|
||||
assert.Equal(t, pbtypes.String("test"), doc.Details().GetFields()["newKey"])
|
||||
assert.False(t, doc.Details().Has("oldKey"))
|
||||
assert.Equal(t, domain.String("test"), doc.Details().Get("newKey"))
|
||||
assert.True(t, doc.HasRelation("newKey"))
|
||||
})
|
||||
t.Run("updateKeys - update object type key", func(t *testing.T) {
|
||||
|
@ -135,7 +131,7 @@ func TestObjectCreator_updateKeys(t *testing.T) {
|
|||
oc.updateKeys(doc, oldToNew)
|
||||
|
||||
// then
|
||||
assert.Nil(t, doc.Details().GetFields()["newKey"])
|
||||
assert.False(t, doc.Details().Has("newKey"))
|
||||
assert.Equal(t, domain.TypeKey(""), doc.ObjectTypeKey())
|
||||
})
|
||||
t.Run("keys are the same", func(t *testing.T) {
|
||||
|
@ -143,9 +139,9 @@ func TestObjectCreator_updateKeys(t *testing.T) {
|
|||
oc := ObjectCreator{}
|
||||
oldToNew := map[string]string{"oldId": "newId", "key": "key"}
|
||||
doc := state.NewDoc("oldId", nil).(*state.State)
|
||||
doc.SetDetails(&types.Struct{Fields: map[string]*types.Value{
|
||||
"key": pbtypes.String("test"),
|
||||
}})
|
||||
doc.SetDetails(domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
"key": domain.String("test"),
|
||||
}))
|
||||
doc.AddRelationLinks(&model.RelationLink{
|
||||
Key: "key",
|
||||
})
|
||||
|
@ -153,7 +149,7 @@ func TestObjectCreator_updateKeys(t *testing.T) {
|
|||
oc.updateKeys(doc, oldToNew)
|
||||
|
||||
// then
|
||||
assert.Equal(t, pbtypes.String("test"), doc.Details().GetFields()["key"])
|
||||
assert.Equal(t, "test", doc.Details().GetString("key"))
|
||||
assert.True(t, doc.HasRelation("key"))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/import/common"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/domain/objectorigin"
|
||||
)
|
||||
|
||||
|
@ -21,7 +21,7 @@ type DataObject struct {
|
|||
}
|
||||
|
||||
type Result struct {
|
||||
Details *types.Struct
|
||||
Details *domain.Details
|
||||
NewID string
|
||||
Err error
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
type derivedObject struct {
|
||||
|
@ -44,21 +43,21 @@ func (d *derivedObject) GetIDAndPayload(ctx context.Context, spaceID string, sn
|
|||
}
|
||||
return id, payload, nil
|
||||
}
|
||||
rawUniqueKey := pbtypes.GetString(sn.Snapshot.Data.Details, bundle.RelationKeyUniqueKey.String())
|
||||
rawUniqueKey := sn.Snapshot.Data.Details.GetString(bundle.RelationKeyUniqueKey)
|
||||
uniqueKey, err := domain.UnmarshalUniqueKey(rawUniqueKey)
|
||||
if err != nil {
|
||||
uniqueKey, err = domain.NewUniqueKey(sn.SbType, sn.Snapshot.Data.Key)
|
||||
uniqueKey, err = domain.NewUniqueKey(sn.Snapshot.SbType, sn.Snapshot.Data.Key)
|
||||
if err != nil {
|
||||
return "", treestorage.TreeStorageCreatePayload{}, fmt.Errorf("create unique key from %s and %q: %w", sn.SbType, sn.Snapshot.Data.Key, err)
|
||||
return "", treestorage.TreeStorageCreatePayload{}, fmt.Errorf("create unique key from %s and %q: %w", sn.Snapshot.SbType, sn.Snapshot.Data.Key, err)
|
||||
}
|
||||
}
|
||||
|
||||
var key string
|
||||
if d.isDeletedObject(spaceID, uniqueKey.Marshal()) {
|
||||
key = bson.NewObjectId().Hex()
|
||||
uniqueKey, err = domain.NewUniqueKey(sn.SbType, key)
|
||||
uniqueKey, err = domain.NewUniqueKey(sn.Snapshot.SbType, key)
|
||||
if err != nil {
|
||||
return "", treestorage.TreeStorageCreatePayload{}, fmt.Errorf("create unique key from %s: %w", sn.SbType, err)
|
||||
return "", treestorage.TreeStorageCreatePayload{}, fmt.Errorf("create unique key from %s: %w", sn.Snapshot.SbType, err)
|
||||
}
|
||||
}
|
||||
d.internalKey = key
|
||||
|
@ -80,16 +79,16 @@ func (d *derivedObject) GetInternalKey(sbType sb.SmartBlockType) string {
|
|||
|
||||
func (d *derivedObject) isDeletedObject(spaceId string, uniqueKey string) bool {
|
||||
ids, _, err := d.objectStore.SpaceIndex(spaceId).QueryObjectIds(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeyUniqueKey.String(),
|
||||
Value: pbtypes.String(uniqueKey),
|
||||
RelationKey: bundle.RelationKeyUniqueKey,
|
||||
Value: domain.String(uniqueKey),
|
||||
},
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeyIsDeleted.String(),
|
||||
Value: pbtypes.Bool(true),
|
||||
RelationKey: bundle.RelationKeyIsDeleted,
|
||||
Value: domain.Bool(true),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -98,16 +97,16 @@ func (d *derivedObject) isDeletedObject(spaceId string, uniqueKey string) bool {
|
|||
|
||||
func (d *derivedObject) getInternalKey(spaceID, objectId string) (string, error) {
|
||||
ids, err := d.objectStore.SpaceIndex(spaceID).Query(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeyId.String(),
|
||||
Value: pbtypes.String(objectId),
|
||||
RelationKey: bundle.RelationKeyId,
|
||||
Value: domain.String(objectId),
|
||||
},
|
||||
},
|
||||
})
|
||||
if err == nil && len(ids) > 0 {
|
||||
uniqueKey := pbtypes.GetString(ids[0].Details, bundle.RelationKeyUniqueKey.String())
|
||||
uniqueKey := ids[0].Details.GetString(bundle.RelationKeyUniqueKey)
|
||||
key, err := domain.UnmarshalUniqueKey(uniqueKey)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
|
|
|
@ -7,21 +7,18 @@ import (
|
|||
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/import/common"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/domain/objectorigin"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace"
|
||||
"github.com/anyproto/anytype-heart/space/mock_space"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func TestDerivedObject_GetIDAndPayload(t *testing.T) {
|
||||
|
@ -32,15 +29,15 @@ func TestDerivedObject_GetIDAndPayload(t *testing.T) {
|
|||
deriveObject := newDerivedObject(newExistingObject(sf), service, sf)
|
||||
sn := &common.Snapshot{
|
||||
Id: "oldId",
|
||||
Snapshot: &pb.ChangeSnapshot{
|
||||
Data: &model.SmartBlockSnapshotBase{
|
||||
Details: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyUniqueKey.String(): pbtypes.String("key"),
|
||||
}},
|
||||
Snapshot: &common.SnapshotModel{
|
||||
Data: &common.StateSnapshot{
|
||||
Details: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyUniqueKey: domain.String("key"),
|
||||
}),
|
||||
Key: "oldKey",
|
||||
},
|
||||
SbType: coresb.SmartBlockTypePage,
|
||||
},
|
||||
SbType: coresb.SmartBlockTypePage,
|
||||
}
|
||||
space := mock_clientspace.NewMockSpace(t)
|
||||
service.EXPECT().Get(context.Background(), "spaceId").Return(space, nil)
|
||||
|
@ -52,9 +49,9 @@ func TestDerivedObject_GetIDAndPayload(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
sf.AddObjects(t, "spaceId", []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String(uniqueKey.Marshal()),
|
||||
bundle.RelationKeyId: pbtypes.String("oldId"),
|
||||
bundle.RelationKeyIsDeleted: pbtypes.Bool(true),
|
||||
bundle.RelationKeyUniqueKey: domain.String(uniqueKey.Marshal()),
|
||||
bundle.RelationKeyId: domain.String("oldId"),
|
||||
bundle.RelationKeyIsDeleted: domain.Bool(true),
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -63,7 +60,7 @@ func TestDerivedObject_GetIDAndPayload(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
assert.NotEqual(t, deriveObject.GetInternalKey(sn.SbType), "key")
|
||||
assert.NotEqual(t, deriveObject.GetInternalKey(sn.Snapshot.SbType), "key")
|
||||
assert.Equal(t, "newId", id)
|
||||
})
|
||||
t.Run("existing object", func(t *testing.T) {
|
||||
|
@ -73,27 +70,27 @@ func TestDerivedObject_GetIDAndPayload(t *testing.T) {
|
|||
deriveObject := newDerivedObject(newExistingObject(sf), service, sf)
|
||||
sn := &common.Snapshot{
|
||||
Id: "oldId",
|
||||
Snapshot: &pb.ChangeSnapshot{
|
||||
Data: &model.SmartBlockSnapshotBase{
|
||||
Details: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String("name"),
|
||||
bundle.RelationKeyRelationFormat.String(): pbtypes.Int64(int64(model.RelationFormat_number)),
|
||||
}},
|
||||
Snapshot: &common.SnapshotModel{
|
||||
Data: &common.StateSnapshot{
|
||||
Details: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyName: domain.String("name"),
|
||||
bundle.RelationKeyRelationFormat: domain.Int64(int64(model.RelationFormat_number)),
|
||||
}),
|
||||
},
|
||||
SbType: coresb.SmartBlockTypeRelation,
|
||||
},
|
||||
SbType: coresb.SmartBlockTypeRelation,
|
||||
}
|
||||
|
||||
uniqueKey, err := domain.NewUniqueKey(coresb.SmartBlockTypeRelation, "oldKey")
|
||||
assert.Nil(t, err)
|
||||
sf.AddObjects(t, "spaceId", []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeyUniqueKey: pbtypes.String(uniqueKey.Marshal()),
|
||||
bundle.RelationKeyId: pbtypes.String("oldId"),
|
||||
bundle.RelationKeyName: pbtypes.String("name"),
|
||||
bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_number)),
|
||||
bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)),
|
||||
bundle.RelationKeySpaceId: pbtypes.String("spaceId"),
|
||||
bundle.RelationKeyUniqueKey: domain.String(uniqueKey.Marshal()),
|
||||
bundle.RelationKeyId: domain.String("oldId"),
|
||||
bundle.RelationKeyName: domain.String("name"),
|
||||
bundle.RelationKeyRelationFormat: domain.Int64(int64(model.RelationFormat_number)),
|
||||
bundle.RelationKeyLayout: domain.Int64(int64(model.ObjectType_relation)),
|
||||
bundle.RelationKeySpaceId: domain.String("spaceId"),
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -7,12 +7,12 @@ import (
|
|||
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/import/common"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
sb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/database"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
type existingObject struct {
|
||||
|
@ -37,25 +37,25 @@ func (e *existingObject) GetIDAndPayload(_ context.Context, spaceID string, sn *
|
|||
return id, treestorage.TreeStorageCreatePayload{}, nil
|
||||
}
|
||||
}
|
||||
if sn.SbType == sb.SmartBlockTypeRelationOption {
|
||||
if sn.Snapshot.SbType == sb.SmartBlockTypeRelationOption {
|
||||
return e.getExistingRelationOption(sn, spaceID), treestorage.TreeStorageCreatePayload{}, nil
|
||||
}
|
||||
if sn.SbType == sb.SmartBlockTypeRelation {
|
||||
if sn.Snapshot.SbType == sb.SmartBlockTypeRelation {
|
||||
return e.getExistingRelation(sn, spaceID), treestorage.TreeStorageCreatePayload{}, nil
|
||||
}
|
||||
return "", treestorage.TreeStorageCreatePayload{}, nil
|
||||
}
|
||||
|
||||
func (e *existingObject) getObjectByOldAnytypeID(spaceID string, sn *common.Snapshot) (string, error) {
|
||||
oldAnytypeID := pbtypes.GetString(sn.Snapshot.Data.Details, bundle.RelationKeyOldAnytypeID.String())
|
||||
oldAnytypeID := sn.Snapshot.Data.Details.GetString(bundle.RelationKeyOldAnytypeID)
|
||||
|
||||
// Check for imported objects
|
||||
ids, _, err := e.objectStore.SpaceIndex(spaceID).QueryObjectIds(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeyOldAnytypeID.String(),
|
||||
Value: pbtypes.String(oldAnytypeID),
|
||||
RelationKey: bundle.RelationKeyOldAnytypeID,
|
||||
Value: domain.String(oldAnytypeID),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -65,11 +65,11 @@ func (e *existingObject) getObjectByOldAnytypeID(spaceID string, sn *common.Snap
|
|||
|
||||
// Check for derived objects
|
||||
ids, _, err = e.objectStore.SpaceIndex(spaceID).QueryObjectIds(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeyUniqueKey.String(),
|
||||
Value: pbtypes.String(oldAnytypeID), // Old id equals to unique key
|
||||
RelationKey: bundle.RelationKeyUniqueKey,
|
||||
Value: domain.String(oldAnytypeID), // Old id equals to unique key
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -81,13 +81,13 @@ func (e *existingObject) getObjectByOldAnytypeID(spaceID string, sn *common.Snap
|
|||
}
|
||||
|
||||
func (e *existingObject) getExistingObject(spaceID string, sn *common.Snapshot) string {
|
||||
source := pbtypes.GetString(sn.Snapshot.Data.Details, bundle.RelationKeySourceFilePath.String())
|
||||
source := sn.Snapshot.Data.Details.GetString(bundle.RelationKeySourceFilePath)
|
||||
ids, _, err := e.objectStore.SpaceIndex(spaceID).QueryObjectIds(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeySourceFilePath.String(),
|
||||
Value: pbtypes.String(source),
|
||||
RelationKey: bundle.RelationKeySourceFilePath,
|
||||
Value: domain.String(source),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -98,24 +98,24 @@ func (e *existingObject) getExistingObject(spaceID string, sn *common.Snapshot)
|
|||
}
|
||||
|
||||
func (e *existingObject) getExistingRelationOption(snapshot *common.Snapshot, spaceID string) string {
|
||||
name := pbtypes.GetString(snapshot.Snapshot.Data.Details, bundle.RelationKeyName.String())
|
||||
key := pbtypes.GetString(snapshot.Snapshot.Data.Details, bundle.RelationKeyRelationKey.String())
|
||||
name := snapshot.Snapshot.Data.Details.GetString(bundle.RelationKeyName)
|
||||
key := snapshot.Snapshot.Data.Details.GetString(bundle.RelationKeyRelationKey)
|
||||
ids, _, err := e.objectStore.SpaceIndex(spaceID).QueryObjectIds(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Value: pbtypes.String(name),
|
||||
RelationKey: bundle.RelationKeyName,
|
||||
Value: domain.String(name),
|
||||
},
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeyRelationKey.String(),
|
||||
Value: pbtypes.String(key),
|
||||
RelationKey: bundle.RelationKeyRelationKey,
|
||||
Value: domain.String(key),
|
||||
},
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeyLayout.String(),
|
||||
Value: pbtypes.Int64(int64(model.ObjectType_relationOption)),
|
||||
RelationKey: bundle.RelationKeyLayout,
|
||||
Value: domain.Int64(model.ObjectType_relationOption),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -126,24 +126,24 @@ func (e *existingObject) getExistingRelationOption(snapshot *common.Snapshot, sp
|
|||
}
|
||||
|
||||
func (e *existingObject) getExistingRelation(snapshot *common.Snapshot, spaceID string) string {
|
||||
name := pbtypes.GetString(snapshot.Snapshot.Data.Details, bundle.RelationKeyName.String())
|
||||
format := pbtypes.GetFloat64(snapshot.Snapshot.Data.Details, bundle.RelationKeyRelationFormat.String())
|
||||
name := snapshot.Snapshot.Data.Details.GetString(bundle.RelationKeyName)
|
||||
format := snapshot.Snapshot.Data.Details.GetFloat64(bundle.RelationKeyRelationFormat)
|
||||
ids, _, err := e.objectStore.SpaceIndex(spaceID).QueryObjectIds(database.Query{
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Value: pbtypes.String(name),
|
||||
RelationKey: bundle.RelationKeyName,
|
||||
Value: domain.String(name),
|
||||
},
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeyRelationFormat.String(),
|
||||
Value: pbtypes.Float64(format),
|
||||
RelationKey: bundle.RelationKeyRelationFormat,
|
||||
Value: domain.Float64(format),
|
||||
},
|
||||
{
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
RelationKey: bundle.RelationKeyLayout.String(),
|
||||
Value: pbtypes.Int64(int64(model.ObjectType_relation)),
|
||||
RelationKey: bundle.RelationKeyLayout,
|
||||
Value: domain.Int64(model.ObjectType_relation),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/import/common"
|
||||
"github.com/anyproto/anytype-heart/core/domain/objectorigin"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
type fileObject struct {
|
||||
|
@ -26,7 +25,7 @@ func (o *fileObject) GetIDAndPayload(ctx context.Context, spaceId string, sn *co
|
|||
return "", treestorage.TreeStorageCreatePayload{}, err
|
||||
}
|
||||
|
||||
filePath := pbtypes.GetString(sn.Snapshot.Data.Details, bundle.RelationKeySource.String())
|
||||
filePath := sn.Snapshot.Data.Details.GetString(bundle.RelationKeySource)
|
||||
if filePath != "" {
|
||||
var encryptionKeys map[string]string
|
||||
if sn.Snapshot.Data.FileInfo != nil {
|
||||
|
@ -35,8 +34,7 @@ func (o *fileObject) GetIDAndPayload(ctx context.Context, spaceId string, sn *co
|
|||
encryptionKeys[key.Path] = key.Key
|
||||
}
|
||||
}
|
||||
name := pbtypes.GetString(sn.Snapshot.Data.Details, bundle.RelationKeyName.String())
|
||||
fileObjectId, err := uploadFile(ctx, o.blockService, spaceId, name, filePath, origin, encryptionKeys)
|
||||
fileObjectId, err := uploadFile(ctx, o.blockService, spaceId, filePath, origin, encryptionKeys, sn.Snapshot.Data.Details)
|
||||
if err != nil {
|
||||
log.Error("handling file object: upload file", zap.Error(err))
|
||||
return id, payload, nil
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block"
|
||||
|
@ -18,7 +17,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/filestore"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
// oldFile represents file in pre Files-as-Objects format
|
||||
|
@ -29,7 +27,7 @@ type oldFile struct {
|
|||
}
|
||||
|
||||
func (f *oldFile) GetIDAndPayload(ctx context.Context, spaceId string, sn *common.Snapshot, _ time.Time, _ bool, origin objectorigin.ObjectOrigin) (string, treestorage.TreeStorageCreatePayload, error) {
|
||||
fileId := pbtypes.GetString(sn.Snapshot.Data.Details, bundle.RelationKeyId.String())
|
||||
fileId := sn.Snapshot.Data.Details.GetString(bundle.RelationKeyId)
|
||||
filesKeys := map[string]string{}
|
||||
for _, fileKeys := range sn.Snapshot.FileKeys {
|
||||
if fileKeys.Hash == fileId {
|
||||
|
@ -38,10 +36,9 @@ func (f *oldFile) GetIDAndPayload(ctx context.Context, spaceId string, sn *commo
|
|||
}
|
||||
}
|
||||
|
||||
filePath := pbtypes.GetString(sn.Snapshot.Data.Details, bundle.RelationKeySource.String())
|
||||
filePath := sn.Snapshot.Data.Details.GetString(bundle.RelationKeySource)
|
||||
if filePath != "" {
|
||||
name := pbtypes.GetString(sn.Snapshot.Data.Details, bundle.RelationKeyName.String())
|
||||
fileObjectId, err := uploadFile(ctx, f.blockService, spaceId, name, filePath, origin, filesKeys)
|
||||
fileObjectId, err := uploadFile(ctx, f.blockService, spaceId, filePath, origin, filesKeys, sn.Snapshot.Data.Details)
|
||||
if err != nil {
|
||||
log.Error("handling old file object: upload file", zap.Error(err))
|
||||
}
|
||||
|
@ -64,14 +61,17 @@ func (f *oldFile) GetIDAndPayload(ctx context.Context, spaceId string, sn *commo
|
|||
return objectId, treestorage.TreeStorageCreatePayload{}, nil
|
||||
}
|
||||
|
||||
func uploadFile(ctx context.Context, blockService *block.Service, spaceId string, name string, filePath string, origin objectorigin.ObjectOrigin, encryptionKeys map[string]string) (string, error) {
|
||||
func uploadFile(
|
||||
ctx context.Context,
|
||||
blockService *block.Service,
|
||||
spaceId, filePath string,
|
||||
origin objectorigin.ObjectOrigin,
|
||||
encryptionKeys map[string]string,
|
||||
details *domain.Details,
|
||||
) (string, error) {
|
||||
params := pb.RpcFileUploadRequest{
|
||||
SpaceId: spaceId,
|
||||
Details: &types.Struct{
|
||||
Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String(name),
|
||||
},
|
||||
},
|
||||
Details: details.CopyOnlyKeys(bundle.RelationKeyName, bundle.RelationKeyIsHiddenDiscovery).ToProto(),
|
||||
}
|
||||
|
||||
if strings.HasPrefix(filePath, "http://") || strings.HasPrefix(filePath, "https://") {
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/domain/objectorigin"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
type participant struct{}
|
||||
|
@ -21,7 +20,7 @@ func newParticipant() *participant {
|
|||
}
|
||||
|
||||
func (w *participant) GetIDAndPayload(ctx context.Context, spaceID string, sn *common.Snapshot, _ time.Time, _ bool, _ objectorigin.ObjectOrigin) (string, treestorage.TreeStorageCreatePayload, error) {
|
||||
participantId := pbtypes.GetString(sn.Snapshot.Data.Details, bundle.RelationKeyId.String())
|
||||
participantId := sn.Snapshot.Data.Details.GetString(bundle.RelationKeyId)
|
||||
splitId := strings.Split(participantId, "_")
|
||||
identity := splitId[len(splitId)-1]
|
||||
newParticipantID := domain.NewParticipantId(spaceID, identity)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue