Iterator.Next() method

This commit is contained in:
Ian Norden 2020-09-10 22:53:34 -05:00
parent 470bdc5ed4
commit f5a12a8d3f
3 changed files with 26 additions and 20 deletions

View File

@ -29,7 +29,7 @@ import (
var errNotSupported = errors.New("this operation is not supported")
var (
const (
hasPgStr = "SELECT exists(select 1 from eth.key_preimages WHERE eth_key = $1)"
getPgStr = "SELECT data FROM public.blocks INNER JOIN eth.key_preimages ON (ipfs_key = blocks.key) WHERE eth_key = $1"
putPgStr = "INSERT INTO public.blocks (key, data) VALUES ($1, $2) ON CONFLICT (key) DO NOTHING"

View File

@ -19,17 +19,25 @@ package pgipfsethdb
import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/jmoiron/sqlx"
"github.com/sirupsen/logrus"
)
const (
nextPgStr = `SELECT key, data FROM public.blocks
INNER JOIN eth.key_preimages ON (ipfs_key = key)
WHERE eth_key > $1 ORDER BY eth_key LIMIT 1`
)
type nextModel struct {
Key []byte `db:"eth_key"`
Value []byte `db:"data"`
}
// Iterator is the type that satisfies the ethdb.Iterator interface for PG-IPFS Ethereum data using a direct Postgres connection
// Iteratee interface is used in Geth for various tests, trie/sync_bloom.go (for fast sync),
// rawdb.InspectDatabase, and the new core/state/snapshot features.
// This should not be confused with trie.NodeIterator or state.NodeIteraor (which can be constructed
// from the ethdb.KeyValueStoreand ethdb.Database interfaces)
type Iterator struct {
db *sqlx.DB
currentKey, prefix []byte
err error
db *sqlx.DB
currentKey, prefix, currentValue []byte
err error
}
// NewIterator returns an ethdb.Iterator interface for PG-IPFS
@ -45,9 +53,14 @@ func NewIterator(start, prefix []byte, db *sqlx.DB) ethdb.Iterator {
// Next moves the iterator to the next key/value pair
// It returns whether the iterator is exhausted
func (i *Iterator) Next() bool {
// this is complicated by the ipfs db keys not being the keccak256 hashes
// go-ethereum usage of this method expects the iteration to occur over keccak256 keys
panic("implement me: Next")
next := new(nextModel)
if err := i.db.Get(next, nextPgStr, i.currentKey); err != nil {
logrus.Errorf("iterator.Next() error: %v", err)
i.currentKey, i.currentValue = nil, nil
return false
}
i.currentKey, i.currentValue = next.Key, next.Value
return true
}
// Error satisfies the ethdb.Iterator interface
@ -70,14 +83,7 @@ func (i *Iterator) Key() []byte {
// The caller should not modify the contents of the returned slice
// and its contents may change on the next call to Next
func (i *Iterator) Value() []byte {
mhKey, err := MultihashKeyFromKeccak256(i.currentKey)
if err != nil {
i.err = err
return nil
}
var data []byte
i.err = i.db.Get(&data, getPgStr, mhKey)
return data
return i.currentValue
}
// Release satisfies the ethdb.Iterator interface

View File

@ -49,9 +49,9 @@ func DatastoreKeyFromGethKey(h []byte) (string, error) {
case Prefixed, Suffixed:
// This data is not mapped by hash => content by geth, store it using the prefixed/suffixed key directly
// I.e. the public.blocks datastore key == the hex representation of the geth key
// Alternatively, decompose the data and derive the hash
return common.Bytes2Hex(h), nil
default:
return "", fmt.Errorf("invalid formatting of database key: %x", h)
}
}