Files
zitadel/backend/v3/storage/database/database.go
T
61cab8878e feat(backend): state persisted objects (#9870)
This PR initiates the rework of Zitadel's backend to state-persisted
objects. This change is a step towards a more scalable and maintainable
architecture.

## Changes

* **New `/backend/v3` package**: A new package structure has been
introduced to house the reworked backend logic. This includes:
* `domain`: Contains the core business logic, commands, and repository
interfaces.
* `storage`: Implements the repository interfaces for database
interactions with new transactional tables.
  * `telemetry`: Provides logging and tracing capabilities.
* **Transactional Tables**: New database tables have been defined for
`instances`, `instance_domains`, `organizations`, and `org_domains`.
* **Projections**: New projections have been created to populate the new
relational tables from the existing event store, ensuring data
consistency during the migration.
* **Repositories**: New repositories provide an abstraction layer for
accessing and manipulating the data in the new tables.
* **Setup**: A new setup step for `TransactionalTables` has been added
to manage the database migrations for the new tables.

This PR lays the foundation for future work to fully transition to
state-persisted objects for these components, which will improve
performance and simplify data access patterns.

This PR initiates the rework of ZITADEL's backend to state-persisted
objects. This is a foundational step towards a new architecture that
will improve performance and maintainability.

The following objects are migrated from event-sourced aggregates to
state-persisted objects:

* Instances
  * incl. Domains
* Orgs
  * incl. Domains

The structure of the new backend implementation follows the software
architecture defined in this [wiki
page](https://github.com/zitadel/zitadel/wiki/Software-Architecturel).

This PR includes:

* The initial implementation of the new transactional repositories for
the objects listed above.
* Projections to populate the new relational tables from the existing
event store.
* Adjustments to the build and test process to accommodate the new
backend structure.

This is a work in progress and further changes will be made to complete
the migration.

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Iraq Jaber <[email protected]>
Co-authored-by: Iraq <[email protected]>
Co-authored-by: Tim Möhlmann <[email protected]>
2025-09-05 09:54:34 +01:00

84 lines
2.0 KiB
Go

package database
import (
"context"
)
// Pool is a connection pool. e.g. pgxpool
type Pool interface {
Beginner
QueryExecutor
Migrator
Acquire(ctx context.Context) (Client, error)
Close(ctx context.Context) error
}
type PoolTest interface {
Pool
// MigrateTest is the same as [Migrator] but executes the migrations multiple times instead of only once.
MigrateTest(ctx context.Context) error
}
// Client is a single database connection which can be released back to the pool.
type Client interface {
Beginner
QueryExecutor
Migrator
Release(ctx context.Context) error
}
// Querier is a database client that can execute queries and return rows.
type Querier interface {
Query(ctx context.Context, stmt string, args ...any) (Rows, error)
QueryRow(ctx context.Context, stmt string, args ...any) Row
}
// Executor is a database client that can execute statements.
// It returns the number of rows affected or an error
type Executor interface {
Exec(ctx context.Context, stmt string, args ...any) (int64, error)
}
// QueryExecutor is a database client that can execute queries and statements.
type QueryExecutor interface {
Querier
Executor
}
// Scanner scans a single row of data into the destination.
type Scanner interface {
Scan(dest ...any) error
}
// Row is an abstraction of sql.Row.
type Row interface {
Scanner
}
// Rows is an abstraction of sql.Rows.
type Rows interface {
Scanner
Next() bool
Close() error
Err() error
}
type CollectableRows interface {
// Collect collects all rows and scans them into dest.
// dest must be a pointer to a slice of pointer to structs
// e.g. *[]*MyStruct
// Rows are closed after this call.
Collect(dest any) error
// CollectFirst collects the first row and scans it into dest.
// dest must be a pointer to a struct
// e.g. *MyStruct{}
// Rows are closed after this call.
CollectFirst(dest any) error
// CollectExactlyOneRow collects exactly one row and scans it into dest.
// e.g. *MyStruct{}
// Rows are closed after this call.
CollectExactlyOneRow(dest any) error
}