cosmos-sdk/indexer/postgres/indexer.go
Aaron Craelius d273ae03da
feat(schema/indexer)!: implement start indexing (#21636)
Co-authored-by: Marko <marko@baricevic.me>
2024-09-23 16:09:01 +00:00

97 lines
2.1 KiB
Go

package postgres
import (
"context"
"database/sql"
"errors"
"fmt"
"cosmossdk.io/schema/indexer"
"cosmossdk.io/schema/logutil"
)
type Config struct {
// DatabaseURL is the PostgreSQL connection URL to use to connect to the database.
DatabaseURL string `json:"database_url"`
// DatabaseDriver is the PostgreSQL database/sql driver to use. This defaults to "pgx".
DatabaseDriver string `json:"database_driver"`
// DisableRetainDeletions disables the retain deletions functionality even if it is set in an object type schema.
DisableRetainDeletions bool `json:"disable_retain_deletions"`
}
type indexerImpl struct {
ctx context.Context
db *sql.DB
tx *sql.Tx
opts options
modules map[string]*moduleIndexer
logger logutil.Logger
}
func init() {
indexer.Register("postgres", indexer.Initializer{
InitFunc: startIndexer,
ConfigType: Config{},
})
}
func startIndexer(params indexer.InitParams) (indexer.InitResult, error) {
config, ok := params.Config.Config.(Config)
if !ok {
return indexer.InitResult{}, fmt.Errorf("invalid config type, expected %T got %T", Config{}, params.Config.Config)
}
ctx := params.Context
if ctx == nil {
ctx = context.Background()
}
if config.DatabaseURL == "" {
return indexer.InitResult{}, errors.New("missing database URL")
}
driver := config.DatabaseDriver
if driver == "" {
driver = "pgx"
}
db, err := sql.Open(driver, config.DatabaseURL)
if err != nil {
return indexer.InitResult{}, err
}
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return indexer.InitResult{}, err
}
// commit base schema
_, err = tx.Exec(baseSQL)
if err != nil {
return indexer.InitResult{}, err
}
moduleIndexers := map[string]*moduleIndexer{}
opts := options{
disableRetainDeletions: config.DisableRetainDeletions,
logger: params.Logger,
addressCodec: params.AddressCodec,
}
idx := &indexerImpl{
ctx: ctx,
db: db,
tx: tx,
opts: opts,
modules: moduleIndexers,
logger: params.Logger,
}
return indexer.InitResult{
Listener: idx.listener(),
View: idx,
}, nil
}