Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion .github/workflows/pr-test-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,48 @@ jobs:
set -euo pipefail
readarray -t PACKAGES <<< "$(./scripts/ci/backend-tests/pkgs-with-tests-named.sh -b TestIntegration | ./scripts/ci/backend-tests/shard.sh -N"$SHARD" -d-)"
CGO_ENABLED=0 go test -p=1 -tags=mysql -timeout=8m -run '^TestIntegration' "${PACKAGES[@]}"
ydb:
needs: detect-changes
if: needs.detect-changes.outputs.changed == 'true'
strategy:
matrix:
shard: [
1/16, 2/16, 3/16, 4/16,
5/16, 6/16, 7/16, 8/16,
9/16, 10/16, 11/16, 12/16,
13/16, 14/16, 15/16, 16/16,
]
fail-fast: false

name: YDB (${{ matrix.shard }})
runs-on: ubuntu-x64-large-io
permissions:
contents: read
env:
GRAFANA_TEST_DB: ydb
services:
ydb:
image: ydbplatform/local-ydb:25.2.1.7
options: --hostname=localhost
ports:
- 2136:2136
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Setup Go
uses: actions/[email protected]
with:
go-version-file: go.mod
cache: true
- name: Run tests
env:
SHARD: ${{ matrix.shard }}
run: |
set -euo pipefail
readarray -t PACKAGES <<< "$(./scripts/ci/backend-tests/pkgs-with-tests-named.sh -b TestIntegration | ./scripts/ci/backend-tests/shard.sh -N"$SHARD" -d-)"
CGO_ENABLED=0 go test -p=1 -tags=ydb -timeout=8m -run '^TestIntegration' "${PACKAGES[@]}"
postgres:
needs: detect-changes
if: needs.detect-changes.outputs.changed == 'true'
Expand Down Expand Up @@ -201,7 +243,6 @@ jobs:
set -euo pipefail
readarray -t PACKAGES <<< "$(./scripts/ci/backend-tests/pkgs-with-tests-named.sh -b TestIntegration | ./scripts/ci/backend-tests/shard.sh -N"$SHARD" -d-)"
CGO_ENABLED=0 go test -p=1 -tags=postgres -timeout=8m -run '^TestIntegration' "${PACKAGES[@]}"

# This is the job that is actually required by rulesets.
# We want to only require one job instead of all the individual tests and shards.
# Future work also allows us to start skipping some tests based on changed files.
Expand All @@ -210,6 +251,7 @@ jobs:
- mysql
- postgres
- sqlite
- ydb
# always() is the best function here.
# success() || failure() will skip this function if any need is also skipped.
# That means conditional test suites will fail the entire requirement check.
Expand Down
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,14 @@ test-go-integration-mysql: devenv-mysql ## Run integration tests for mysql backe
$(GO) test $(GO_RACE_FLAG) $(GO_TEST_FLAGS) -p=1 -count=1 -run "^TestIntegration" -covermode=atomic -timeout=10m \
$(shell ./scripts/ci/backend-tests/pkgs-with-tests-named.sh -b TestIntegration | ./scripts/ci/backend-tests/shard.sh -n$(SHARD) -m$(SHARDS) -s)


.PHONY: test-go-integration-ydb
test-go-integration-ydb: devenv-ydb ## Run integration tests for ydb backend with flags.
@echo "test backend integration ydb tests"
GRAFANA_TEST_DB=ydb \
$(GO) test $(GO_RACE_FLAG) $(GO_TEST_FLAGS) -p=1 -count=1 -run "^TestIntegration" -covermode=atomic -timeout=10m \
$(shell ./scripts/ci/backend-tests/pkgs-with-tests-named.sh -b TestIntegration | ./scripts/ci/backend-tests/shard.sh -n$(SHARD) -m$(SHARDS) -s)

.PHONY: test-go-integration-redis
test-go-integration-redis: ## Run integration tests for redis cache.
@echo "test backend integration redis tests"
Expand Down Expand Up @@ -512,6 +520,11 @@ devenv-mysql:
@cd devenv; \
sources=mysql_tests

.PHONY: devenv-ydb
devenv-ydb:
@cd devenv; \
sources=ydb_tests

##@ Helpers

# We separate the protobuf generation because most development tasks on
Expand Down
1 change: 1 addition & 0 deletions devenv/docker/blocks/ydb_tests/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ydb_version=25.2.1.7
6 changes: 6 additions & 0 deletions devenv/docker/blocks/ydb_tests/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ydbtest:
image: ydbplatform/local-ydb:${ydb_version}
hostname: localhost
ports:
- "2136:2136" # Simple
- "8765:8765" # Monitor
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ require (
// Check go.work file for details
github.com/grafana/grafana/pkg/promlib v0.0.8 // @grafana/oss-big-tent
github.com/grafana/grafana/pkg/semconv v0.0.0-20250804150913-990f1c69ecc2 // @grafana/grafana-app-platform-squad
github.com/ydb-platform/ydb-go-sdk/v3 v3.118.0 // @grafana/grafana-search-and-storage
)

// Replace the workspace versions
Expand Down Expand Up @@ -653,7 +654,10 @@ require (
sigs.k8s.io/yaml v1.6.0 // indirect
)

require github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
require (
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/ydb-platform/ydb-go-genproto v0.0.0-20250911135631-b3beddd517d9 // indirect
)

// Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream
replace github.com/crewjam/saml => github.com/grafana/saml v0.4.15-0.20240917091248-ae3bbdad8a56
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2289,6 +2289,8 @@ github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01j
github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
github.com/redis/rueidis v1.0.64 h1:XqgbueDuNV3qFdVdQwAHJl1uNt90zUuAJuzqjH4cw6Y=
github.com/redis/rueidis v1.0.64/go.mod h1:Lkhr2QTgcoYBhxARU7kJRO8SyVlgUuEkcJO1Y8MCluA=
github.com/rekby/fixenv v0.6.1 h1:jUFiSPpajT4WY2cYuc++7Y1zWrnCxnovGCIX72PZniM=
github.com/rekby/fixenv v0.6.1/go.mod h1:/b5LRc06BYJtslRtHKxsPWFT/ySpHV+rWvzTg+XWk4c=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
Expand Down Expand Up @@ -2510,6 +2512,10 @@ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGC
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/ydb-platform/ydb-go-genproto v0.0.0-20250911135631-b3beddd517d9 h1:SKqSRP6/ocY2Z4twOqKEKxpmawVTHTvQiom7hrU6jt0=
github.com/ydb-platform/ydb-go-genproto v0.0.0-20250911135631-b3beddd517d9/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I=
github.com/ydb-platform/ydb-go-sdk/v3 v3.118.0 h1:wLnWJ29yzYdVds3WFRgkzij/2li9dknyRBO7B+reJfY=
github.com/ydb-platform/ydb-go-sdk/v3 v3.118.0/go.mod h1:UEMMk+JMunUveo2j+zlJEJ5I7ntf2+MbimciVNJYnNs=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
Expand Down
6 changes: 2 additions & 4 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,6 @@ github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/cel-go v0.23.2/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo=
github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-jsonnet v0.18.0 h1:/6pTy6g+Jh1a1I2UMoAODkqELFiVIdOxbNwv0DDzoOg=
github.com/google/go-jsonnet v0.18.0/go.mod h1:C3fTzyVJDslXdiTqw/bTFk7vSGyCtH3MGRbDfvEwGd0=
github.com/google/go-pkcs11 v0.3.0 h1:PVRnTgtArZ3QQqTGtbtjtnIkzl2iY2kt24yqbrf7td8=
Expand Down Expand Up @@ -1063,7 +1062,6 @@ github.com/grafana/dskit v0.0.0-20250818234656-8ff9c6532e85/go.mod h1:kImsvJ1xnm
github.com/grafana/go-gelf/v2 v2.0.1 h1:BOChP0h/jLeD+7F9mL7tq10xVkDG15he3T1zHuQaWak=
github.com/grafana/go-gelf/v2 v2.0.1/go.mod h1:lexHie0xzYGwCgiRGcvZ723bSNyNI8ZRD4s0CLobh90=
github.com/grafana/gomemcache v0.0.0-20250228145437-da7b95fd2ac1/go.mod h1:j/s0jkda4UXTemDs7Pgw/vMT06alWc42CHisvYac0qw=
github.com/grafana/gomemcache v0.0.0-20250828162811-a96f6acee2fe/go.mod h1:j/s0jkda4UXTemDs7Pgw/vMT06alWc42CHisvYac0qw=
github.com/grafana/grafana-app-sdk v0.40.1/go.mod h1:4P8h7VB6KcDjX9bAoBQc6IP8iNylxe6bSXLR9gA39gM=
github.com/grafana/grafana-app-sdk v0.41.0 h1:SYHN3U7B1myRKY3UZZDkFsue9TDmAOap0UrQVTqtYBU=
github.com/grafana/grafana-app-sdk v0.41.0/go.mod h1:Wg/3vEZfok1hhIWiHaaJm+FwkosfO98o8KbeLFEnZpY=
Expand Down Expand Up @@ -1497,8 +1495,6 @@ github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
github.com/rekby/fixenv v0.6.1 h1:jUFiSPpajT4WY2cYuc++7Y1zWrnCxnovGCIX72PZniM=
github.com/rekby/fixenv v0.6.1/go.mod h1:/b5LRc06BYJtslRtHKxsPWFT/ySpHV+rWvzTg+XWk4c=
github.com/relvacode/iso8601 v1.6.0 h1:eFXUhMJN3Gz8Rcq82f9DTMW0svjtAVuIEULglM7QHTU=
github.com/relvacode/iso8601 v1.6.0/go.mod h1:FlNp+jz+TXpyRqgmM7tnzHHzBnz776kmAH2h3sZCn0I=
github.com/richardartoul/molecule v1.0.0 h1:+LFA9cT7fn8KF39zy4dhOnwcOwRoqKiBkPqKqya+8+U=
Expand Down Expand Up @@ -1675,6 +1671,7 @@ github.com/ydb-platform/ydb-go-genproto v0.0.0-20241112172322-ea1f63298f77 h1:LY
github.com/ydb-platform/ydb-go-genproto v0.0.0-20241112172322-ea1f63298f77/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I=
github.com/ydb-platform/ydb-go-sdk/v3 v3.108.1 h1:ixAiqjj2S/dNuJqrz4AxSqgw2P5OBMXp68hB5nNriUk=
github.com/ydb-platform/ydb-go-sdk/v3 v3.108.1/go.mod h1:l5sSv153E18VvYcsmr51hok9Sjc16tEC8AXGbwrk+ho=
github.com/ydb-platform/ydb-go-sdk/v3 v3.117.2/go.mod h1:UEMMk+JMunUveo2j+zlJEJ5I7ntf2+MbimciVNJYnNs=
github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA=
github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0=
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
Expand Down Expand Up @@ -1926,6 +1923,7 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
Expand Down
8 changes: 8 additions & 0 deletions pkg/infra/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,11 @@ func IsTestDBMSSQL() bool {

return false
}

func IsTestDBYDB() bool {
if db, present := os.LookupEnv("GRAFANA_TEST_DB"); present {
return db == migrator.YDB
}

return false
}
10 changes: 5 additions & 5 deletions pkg/infra/usagestats/statscollector/concurrent_users.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ func (s *Service) concurrentUsers(ctx context.Context) (*concurrentUsersStats, e
// Retrieves concurrent users stats as a histogram. Buckets are accumulative and upper bound is inclusive.
rawSQL := `
SELECT
COUNT(CASE WHEN tokens <= 3 THEN 1 END) AS bucket_le_3,
COUNT(CASE WHEN tokens <= 6 THEN 1 END) AS bucket_le_6,
COUNT(CASE WHEN tokens <= 9 THEN 1 END) AS bucket_le_9,
COUNT(CASE WHEN tokens <= 12 THEN 1 END) AS bucket_le_12,
COUNT(CASE WHEN tokens <= 15 THEN 1 END) AS bucket_le_15,
COUNT(CASE WHEN tokens <= 3 THEN 1 ELSE NULL END) AS bucket_le_3,
COUNT(CASE WHEN tokens <= 6 THEN 1 ELSE NULL END) AS bucket_le_6,
COUNT(CASE WHEN tokens <= 9 THEN 1 ELSE NULL END) AS bucket_le_9,
COUNT(CASE WHEN tokens <= 12 THEN 1 ELSE NULL END) AS bucket_le_12,
COUNT(CASE WHEN tokens <= 15 THEN 1 ELSE NULL END) AS bucket_le_15,
COUNT(1) AS bucket_le_inf
FROM (select count(1) as tokens from user_auth_token group by user_id) uat;`
_, err := sess.SQL(rawSQL).Get(s.concurrentUserStatsCache.stats)
Expand Down
3 changes: 3 additions & 0 deletions pkg/services/anonymous/anonimpl/anonstore/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ func (s *AnonDBStore) CreateOrUpdateDevice(ctx context.Context, device *Device)
client_ip = excluded.client_ip,
user_agent = excluded.user_agent,
updated_at = excluded.updated_at`
case migrator.YDB:
query = `UPSERT INTO anon_device (device_id, client_ip, user_agent, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5)`
default:
return fmt.Errorf("unsupported database driver: %s", s.sqlStore.GetDBType())
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/services/authz/rbac/store/basic_role_query.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SELECT COALESCE(ou.role, 'None') AS role, u.is_admin
FROM {{ .Ident .UserTable }} as u
LEFT JOIN {{ .Ident .OrgUserTable }} as ou ON ou.user_id = u.id AND ou.org_id = {{ .Arg .Query.OrgID }}
WHERE u.id = {{ .Arg .Query.UserID }}
LEFT JOIN {{ .Ident .OrgUserTable }} as ou ON ou.user_id = u.id
WHERE u.id = {{ .Arg .Query.UserID }} AND ou.org_id = {{ .Arg .Query.OrgID }}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"checksum":"edbc5d2098a249296e989868b3e30835228a6ef4d03a1305bb0b8bf6fd5b887f","data":"3xPR6Xuxqqp8MYf1/tE95gu7ogwkxsfJZ+1f26787pqGaUH6Au20lgwVrPazSXe7VlAH4qi/VsUcuUlSrrTZGHSTLQeryyDqjni9ltP1WpKfW7scBccdwReacZXkoIaALViDl6jjAm+su8g1xVgZwCac8aAAWX9QvYSD4gw="}
17 changes: 17 additions & 0 deletions pkg/services/dashboards/database/migrations/folder_uid_mig.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ func (m *FolderUIDMigration) Exec(sess *xorm.Session, mgrtr *migrator.Migrator)
WHERE d.is_folder = ?`
}

if mgrtr.Dialect.DriverName() == migrator.YDB {
q = `
UPSERT INTO dashboard SELECT folder.uid AS folder_uid, d.created AS created,
d.data as data, d.org_id as org_id, d.slug as slug,
d.title as title, d.updated as updated, d.version as version
FROM dashboard folder JOIN dashboard d ON d.folder_id = folder.id WHERE d.is_folder = ?`
}

r, err := sess.Exec(q, mgrtr.Dialect.BooleanValue(false))
if err != nil {
mgrtr.Logger.Error("Failed to migrate dashboard folder_uid for dashboards", "error", err)
Expand Down Expand Up @@ -68,6 +76,15 @@ func (m *FolderUIDMigration) Exec(sess *xorm.Session, mgrtr *migrator.Migrator)
)
WHERE is_folder = ?`
}

if mgrtr.Dialect.DriverName() == migrator.YDB {
q = `
UPSERT INTO dashboard SELECT folder.parent_uid AS folder_uid, d.created AS created,
d.data as data, d.org_id as org_id, d.slug as slug,
d.title as title, d.updated as updated, d.version as version
FROM folder JOIN dashboard d ON d.org_id = folder.org_id WHERE d.is_folder = ?`
}

r, err = sess.Exec(q, mgrtr.Dialect.BooleanValue(true))
if err != nil {
mgrtr.Logger.Error("Failed to migrate dashboard folder_uid for folders", "error", err)
Expand Down
18 changes: 16 additions & 2 deletions pkg/services/folder/folderimpl/folder.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ func (s *Service) DBMigration(db db.DB) {
SELECT uid, org_id, title, created, updated FROM dashboard WHERE is_folder = true
ON CONFLICT(uid, org_id) DO UPDATE SET title=excluded.title, updated=excluded.updated
`)
} else if db.GetDialect().DriverName() == migrator.YDB {
// covered by UQE_folder_org_id_uid
_, err = sess.Exec(`
UPSERT INTO folder (uid, org_id, title, created, updated)
SELECT uid, org_id, title, created, updated FROM dashboard WHERE is_folder
`)
} else {
// covered by UQE_folder_org_id_uid
_, err = sess.Exec(`
Expand All @@ -183,10 +189,18 @@ func (s *Service) DBMigration(db db.DB) {

if deleteOldFolders {
// covered by UQE_folder_org_id_uid
_, err = sess.Exec(`
q := `
DELETE FROM folder WHERE NOT EXISTS
(SELECT 1 FROM dashboard WHERE dashboard.uid = folder.uid AND dashboard.org_id = folder.org_id AND dashboard.is_folder = true)
`)
`

if db.GetDialect().DriverName() == migrator.YDB {
q = `
DELETE FROM folder ON
SELECT folder.id AS id FROM folder JOIN dashboard ON dashboard.uid = folder.uid
WHERE dashboard.org_id = folder.org_id AND dashboard.is_folder = true`
}
_, err = sess.Exec(q)
}
return err
})
Expand Down
14 changes: 11 additions & 3 deletions pkg/services/folder/folderimpl/sqlstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,11 @@ func (ss *FolderStoreImpl) GetFolders(ctx context.Context, q folder.GetFoldersFr
if q.Limit > 0 {
s.WriteString(` ORDER BY f0.title ASC`)
s.WriteString(` LIMIT ? OFFSET ?`)
args = append(args, q.Limit, (q.Page-1)*q.Limit)
if ss.db.GetDialect().DriverName() == migrator.YDB {
args = append(args, uint64(q.Limit), uint64((q.Page-1)*q.Limit))
} else {
args = append(args, q.Limit, uint64((q.Page-1)*q.Limit))
}
} else if q.OrderByTitle {
s.WriteString(` ORDER BY f0.title ASC`)
}
Expand Down Expand Up @@ -623,10 +627,14 @@ func getFullpathSQL(dialect migrator.Dialect) string {
if dialect.DriverName() == migrator.MySQL {
escaped = `\\/`
}
replaceExpr := "REPLACE"
if dialect.DriverName() == migrator.YDB {
replaceExpr = "Unicode::ReplaceAll"
}
concatCols := make([]string, 0, folder.MaxNestedFolderDepth)
concatCols = append(concatCols, fmt.Sprintf("COALESCE(REPLACE(f0.title, '/', '%s'), '')", escaped))
concatCols = append(concatCols, fmt.Sprintf("COALESCE(%s(f0.title, '/', '%s'), '')", replaceExpr, escaped))
for i := 1; i <= folder.MaxNestedFolderDepth; i++ {
concatCols = append([]string{fmt.Sprintf("COALESCE(REPLACE(f%d.title, '/', '%s'), '')", i, escaped), "'/'"}, concatCols...)
concatCols = append([]string{fmt.Sprintf("COALESCE(%s(f%d.title, '/', '%s'), '')", replaceExpr, i, escaped), "'/'"}, concatCols...)
}
return dialect.Concat(concatCols...)
}
Expand Down
9 changes: 8 additions & 1 deletion pkg/services/sqlstore/database_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"

"github.com/go-sql-driver/mysql"
"github.com/ydb-platform/ydb-go-sdk/v3/sugar"

"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
Expand Down Expand Up @@ -146,7 +147,7 @@ func (dbCfg *DatabaseConfig) buildConnectionString(cfg *setting.Cfg, features fe
protocol = "unix"
}

cnnstr = fmt.Sprintf("%s:%s@%s(%s)/%s?collation=utf8mb4_unicode_ci&allowNativePasswords=true&clientFoundRows=true&parseTime=true",
cnnstr = fmt.Sprintf("%s:%s@%s(%s)/%s?collation=utf8mb4_unicode_ci&allowNativePasswords=true&clientFoundRows=true",
dbCfg.User, dbCfg.Pwd, protocol, dbCfg.Host, dbCfg.Name)

if dbCfg.SslMode == "true" || dbCfg.SslMode == "skip-verify" {
Expand Down Expand Up @@ -210,6 +211,12 @@ func (dbCfg *DatabaseConfig) buildConnectionString(cfg *setting.Cfg, features fe
}

cnnstr += buildExtraConnectionString('&', dbCfg.UrlQueryParams)
case migrator.YDB:
cnnstr = sugar.DSN(dbCfg.Host, dbCfg.Name)

cnnstr += buildExtraConnectionString(' ', dbCfg.UrlQueryParams)

// cnnstr = "grpc://127.0.0.1:2136/local?go_query_mode=query&go_fake_tx=query&go_query_bind=numeric" // TODO:
default:
return fmt.Errorf("unknown database type: %s", dbCfg.Type)
}
Expand Down
8 changes: 5 additions & 3 deletions pkg/services/sqlstore/migrations/accesscontrol/admin_only.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ func (m *adminOnlyMigrator) Exec(sess *xorm.Session, mg *migrator.Migrator) erro

// Find all dashboards and folders that should have only admin permission in acl
// When a dashboard or folder only has admin permission the acl table should be empty and the has_acl set to true

// TODO: check in Postgres
sql := `
SELECT res.uid, res.is_folder, res.org_id
FROM (SELECT dashboard.id, dashboard.uid, dashboard.is_folder, dashboard.org_id, count(dashboard_acl.id) as count
FROM (SELECT dashboard.id, dashboard.uid AS uid, dashboard.is_folder AS is_folder, dashboard.org_id AS org_id, count(dashboard_acl.id) as count
FROM dashboard
LEFT JOIN dashboard_acl ON dashboard.id = dashboard_acl.dashboard_id
WHERE dashboard.has_acl IS TRUE
GROUP BY dashboard.id) as res
WHERE dashboard.has_acl
GROUP BY dashboard.id, dashboard.uid, dashboard.is_folder, dashboard.org_id) as res
WHERE res.count = 0
`

Expand Down
Loading
Loading