diff --git a/internal/storage/postgres/action.go b/internal/storage/postgres/action.go index 78923db..74b4d0e 100644 --- a/internal/storage/postgres/action.go +++ b/internal/storage/postgres/action.go @@ -27,41 +27,38 @@ func NewAction(db *database.Bun) *Action { } func (a *Action) ByBlock(ctx context.Context, height types.Level, limit, offset int) (actions []storage.ActionWithTx, err error) { - query := a.DB().NewSelect().Model(&actions). - Where("action_with_tx.height = ?", height). - Relation("Tx", func(sq *bun.SelectQuery) *bun.SelectQuery { - return sq.Column("hash") - }) + query := a.DB().NewSelect(). + Model((*storage.Action)(nil)). + Where("height = ?", height) query = limitScope(query, limit) - - if offset > 0 { - query = query.Offset(offset) - } - err = query.Scan(ctx) + query = offsetScope(query, offset) + + err = a.DB().NewSelect(). + TableExpr("(?) as action", query). + ColumnExpr("action.*"). + ColumnExpr("tx.hash as tx__hash"). + Join("left join tx on tx.id = action.tx_id"). + Scan(ctx, &actions) return } func (a *Action) ByTxId(ctx context.Context, txId uint64, limit, offset int) (actions []storage.Action, err error) { - query := a.DB().NewSelect().Model(&actions). + query := a.DB().NewSelect(). + Model(&actions). Where("tx_id = ?", txId) - query = limitScope(query, limit) - if offset > 0 { - query = query.Offset(offset) - } + query = limitScope(query, limit) + query = offsetScope(query, offset) err = query.Scan(ctx) return } func (a *Action) ByAddress(ctx context.Context, addressId uint64, filters storage.AddressActionsFilter) (actions []storage.AddressAction, err error) { - query := a.DB().NewSelect().Model(&actions). - Where("address_id = ?", addressId). - Relation("Action"). - Relation("Tx", func(sq *bun.SelectQuery) *bun.SelectQuery { - return sq.Column("hash") - }) + query := a.DB().NewSelect(). + Model((*storage.AddressAction)(nil)). + Where("address_id = ?", addressId) if filters.ActionTypes.Bits > 0 { query = query.Where("action_type IN (?)", bun.In(filters.ActionTypes.Strings())) @@ -69,30 +66,35 @@ func (a *Action) ByAddress(ctx context.Context, addressId uint64, filters storag query = sortScope(query, "action_id", filters.Sort) query = limitScope(query, filters.Limit) - - if filters.Offset > 0 { - query = query.Offset(filters.Offset) - } - - err = query.Scan(ctx) + query = offsetScope(query, filters.Offset) + + err = a.DB().NewSelect(). + TableExpr("(?) as address_action", query). + ColumnExpr("address_action.*"). + ColumnExpr("action.id as action__id, action.height as action__height, action.time as action__time, action.position as action__position, action.type as action__type, action.tx_id as action__tx_id, action.data as action__data"). + ColumnExpr("tx.hash as tx__hash"). + Join("left join tx on tx.id = address_action.tx_id"). + Join("left join action on action.id = address_action.action_id"). + Scan(ctx, &actions) return } func (a *Action) ByRollup(ctx context.Context, rollupId uint64, limit, offset int, sort sdk.SortOrder) (actions []storage.RollupAction, err error) { - query := a.DB().NewSelect().Model(&actions). - Where("rollup_id = ?", rollupId). - Relation("Action"). - Relation("Tx", func(sq *bun.SelectQuery) *bun.SelectQuery { - return sq.Column("hash") - }) + query := a.DB().NewSelect(). + Model((*storage.RollupAction)(nil)). + Where("rollup_id = ?", rollupId) query = sortScope(query, "action_id", sort) query = limitScope(query, limit) - - if offset > 0 { - query = query.Offset(offset) - } - - err = query.Scan(ctx) + query = offsetScope(query, offset) + + err = a.DB().NewSelect(). + TableExpr("(?) as rollup_action", query). + ColumnExpr("rollup_action.*"). + ColumnExpr("action.id as action__id, action.height as action__height, action.time as action__time, action.position as action__position, action.type as action__type, action.tx_id as action__tx_id, action.data as action__data"). + ColumnExpr("tx.hash as tx__hash"). + Join("left join tx on tx.id = rollup_action.tx_id"). + Join("left join action on action.id = rollup_action.action_id"). + Scan(ctx, &actions) return } diff --git a/internal/storage/postgres/action_test.go b/internal/storage/postgres/action_test.go index a0aa53c..d00f8d9 100644 --- a/internal/storage/postgres/action_test.go +++ b/internal/storage/postgres/action_test.go @@ -70,3 +70,22 @@ func (s *StorageTestSuite) TestActionByAddress() { s.Require().EqualValues(types.ActionTypeSequence, action.Action.Type) s.Require().NotNil(action.Action.Data) } + +func (s *StorageTestSuite) TestActionByRollup() { + ctx, ctxCancel := context.WithTimeout(context.Background(), 5*time.Second) + defer ctxCancel() + + actions, err := s.storage.Action.ByRollup(ctx, 1, 1, 0, sdk.SortOrderDesc) + s.Require().NoError(err) + s.Require().Len(actions, 1) + + action := actions[0] + s.Require().EqualValues(7316, action.Height) + s.Require().EqualValues(1, action.ActionId) + s.Require().EqualValues(1, action.ActionId) + s.Require().NotNil(action.Tx) + s.Require().NotNil(action.Action) + s.Require().EqualValues(1, action.Action.TxId) + s.Require().EqualValues(types.ActionTypeSequence, action.Action.Type) + s.Require().NotNil(action.Action.Data) +} diff --git a/internal/storage/postgres/block.go b/internal/storage/postgres/block.go index de081a0..03d4153 100644 --- a/internal/storage/postgres/block.go +++ b/internal/storage/postgres/block.go @@ -28,18 +28,26 @@ func NewBlocks(db *database.Bun) *Blocks { // ByHeight - func (b *Blocks) ByHeight(ctx context.Context, height types.Level, withStats bool) (block storage.Block, err error) { - query := b.DB().NewSelect().Model(&block). - Where("block.height = ?", height). - Relation("Proposer", func(sq *bun.SelectQuery) *bun.SelectQuery { - return sq.Column("id", "address", "name") - }). + subQuery := b.DB().NewSelect(). + Model((*storage.Block)(nil)). + Where("height = ?", height). Limit(1) + query := b.DB().NewSelect(). + TableExpr("(?) as block", subQuery). + ColumnExpr("block.*"). + ColumnExpr("validator.id as proposer__id, validator.address as proposer__address, validator.name as proposer__name"). + Join("left join validator on block.proposer_id = validator.id") + if withStats { - query = query.Relation("Stats") + query = query. + ColumnExpr("stats.id AS stats__id, stats.height AS stats__height, stats.time AS stats__time, stats.tx_count AS stats__tx_count"). + ColumnExpr("stats.block_time AS stats__block_time, stats.bytes_in_block AS stats__bytes_in_block"). + ColumnExpr("stats.supply_change AS stats__supply_change, stats.fee AS stats__fee, stats.gas_used AS stats__gas_used, stats.gas_wanted AS stats__gas_wanted"). + Join("left join block_stats as stats ON stats.height = block.height") } - err = query.Scan(ctx) + err = query.Scan(ctx, &block) return } @@ -57,15 +65,21 @@ func (b *Blocks) Last(ctx context.Context) (block storage.Block, err error) { // ByHash - func (b *Blocks) ByHash(ctx context.Context, hash []byte) (block storage.Block, err error) { - err = b.DB().NewSelect(). - Model(&block). + subQuery := b.DB().NewSelect(). + Model((*storage.Block)(nil)). Where("hash = ?", hash). - Relation("Stats"). - Relation("Proposer", func(sq *bun.SelectQuery) *bun.SelectQuery { - return sq.Column("id", "address", "name") - }). - Limit(1). - Scan(ctx) + Limit(1) + + err = b.DB().NewSelect(). + TableExpr("(?) as block", subQuery). + ColumnExpr("block.*"). + ColumnExpr("validator.id as proposer__id, validator.address as proposer__address, validator.name as proposer__name"). + ColumnExpr("stats.id AS stats__id, stats.height AS stats__height, stats.time AS stats__time, stats.tx_count AS stats__tx_count"). + ColumnExpr("stats.block_time AS stats__block_time, stats.bytes_in_block AS stats__bytes_in_block"). + ColumnExpr("stats.supply_change AS stats__supply_change, stats.fee AS stats__fee, stats.gas_used AS stats__gas_used, stats.gas_wanted AS stats__gas_wanted"). + Join("left join validator on block.proposer_id = validator.id"). + Join("left join block_stats as stats ON stats.height = block.height"). + Scan(ctx, &block) return } @@ -103,11 +117,21 @@ func (b *Blocks) ByProposer(ctx context.Context, proposerId uint64, limit, offse } func (b *Blocks) ByIdWithRelations(ctx context.Context, id uint64) (block storage.Block, err error) { - err = b.DB().NewSelect().Model(&block). - Where("block.id = ?", id). - Limit(1). - Relation("Stats"). - Relation("Proposer"). - Scan(ctx) + query := b.DB().NewSelect(). + Model((*storage.Block)(nil)). + Where("id = ?", id). + Limit(1) + + err = b.DB().NewSelect(). + TableExpr("(?) as block", query). + ColumnExpr("block.*"). + ColumnExpr("validator.id as proposer__id, validator.address as proposer__address, validator.name as proposer__name, validator.pubkey as proposer__pubkey, validator.pubkey_type as proposer__pubkey_type, validator.power as proposer__power, validator.height as proposer__height"). + ColumnExpr("stats.id AS stats__id, stats.height AS stats__height, stats.time AS stats__time, stats.tx_count AS stats__tx_count"). + ColumnExpr("stats.block_time AS stats__block_time, stats.bytes_in_block AS stats__bytes_in_block"). + ColumnExpr("stats.supply_change AS stats__supply_change, stats.fee AS stats__fee, stats.gas_used AS stats__gas_used, stats.gas_wanted AS stats__gas_wanted"). + Join("left join validator on block.proposer_id = validator.id"). + Join("left join block_stats as stats ON stats.height = block.height"). + Scan(ctx, &block) + return }