Iterator.Next() method
This commit is contained in:
parent
470bdc5ed4
commit
f5a12a8d3f
@ -29,7 +29,7 @@ import (
|
|||||||
|
|
||||||
var errNotSupported = errors.New("this operation is not supported")
|
var errNotSupported = errors.New("this operation is not supported")
|
||||||
|
|
||||||
var (
|
const (
|
||||||
hasPgStr = "SELECT exists(select 1 from eth.key_preimages WHERE eth_key = $1)"
|
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"
|
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"
|
putPgStr = "INSERT INTO public.blocks (key, data) VALUES ($1, $2) ON CONFLICT (key) DO NOTHING"
|
||||||
|
@ -19,17 +19,25 @@ package pgipfsethdb
|
|||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/jmoiron/sqlx"
|
"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
|
// 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 {
|
type Iterator struct {
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
currentKey, prefix []byte
|
currentKey, prefix, currentValue []byte
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIterator returns an ethdb.Iterator interface for PG-IPFS
|
// 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
|
// Next moves the iterator to the next key/value pair
|
||||||
// It returns whether the iterator is exhausted
|
// It returns whether the iterator is exhausted
|
||||||
func (i *Iterator) Next() bool {
|
func (i *Iterator) Next() bool {
|
||||||
// this is complicated by the ipfs db keys not being the keccak256 hashes
|
next := new(nextModel)
|
||||||
// go-ethereum usage of this method expects the iteration to occur over keccak256 keys
|
if err := i.db.Get(next, nextPgStr, i.currentKey); err != nil {
|
||||||
panic("implement me: Next")
|
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
|
// 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
|
// The caller should not modify the contents of the returned slice
|
||||||
// and its contents may change on the next call to Next
|
// and its contents may change on the next call to Next
|
||||||
func (i *Iterator) Value() []byte {
|
func (i *Iterator) Value() []byte {
|
||||||
mhKey, err := MultihashKeyFromKeccak256(i.currentKey)
|
return i.currentValue
|
||||||
if err != nil {
|
|
||||||
i.err = err
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var data []byte
|
|
||||||
i.err = i.db.Get(&data, getPgStr, mhKey)
|
|
||||||
return data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release satisfies the ethdb.Iterator interface
|
// Release satisfies the ethdb.Iterator interface
|
||||||
|
@ -49,9 +49,9 @@ func DatastoreKeyFromGethKey(h []byte) (string, error) {
|
|||||||
case Prefixed, Suffixed:
|
case Prefixed, Suffixed:
|
||||||
// This data is not mapped by hash => content by geth, store it using the prefixed/suffixed key directly
|
// 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
|
// 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
|
return common.Bytes2Hex(h), nil
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("invalid formatting of database key: %x", h)
|
return "", fmt.Errorf("invalid formatting of database key: %x", h)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user