2023-06-14 12:43:34 +00:00
// VulcanizeDB
// Copyright © 2021 Vulcanize
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package postgres
import (
2023-06-21 15:49:57 +00:00
"fmt"
2023-06-23 12:42:55 +00:00
"github.com/cerc-io/plugeth-statediff/indexer/database/sql"
"github.com/cerc-io/plugeth-statediff/indexer/shared/schema"
2023-06-14 12:43:34 +00:00
)
var _ sql . Database = & DB { }
const (
createNodeStm = ` INSERT INTO nodes ( genesis_block , network_id , node_id , client_name , chain_id ) VALUES ( $ 1 , $ 2 , $ 3 , $ 4 , $ 5 )
ON CONFLICT ( node_id ) DO NOTHING `
)
// NewPostgresDB returns a postgres.DB using the provided driver
func NewPostgresDB ( driver sql . Driver , upsert bool ) * DB {
return & DB { upsert , driver }
}
// DB implements sql.Database using a configured driver and Postgres statement syntax
type DB struct {
upsert bool
sql . Driver
}
2023-06-24 04:04:57 +00:00
// MaxHeaderStm satisfies the sql.Statements interface
func ( db * DB ) MaxHeaderStm ( ) string {
return fmt . Sprintf ( "SELECT block_number, block_hash, parent_hash, cid, td, node_ids, reward, state_root, tx_root, receipt_root, uncles_hash, bloom, timestamp, coinbase FROM %s ORDER BY block_number DESC LIMIT 1" , schema . TableHeader . Name )
}
// ExistsHeaderStm satisfies the sql.Statements interface
2023-06-21 15:49:57 +00:00
func ( db * DB ) ExistsHeaderStm ( ) string {
2023-06-24 04:04:57 +00:00
return fmt . Sprintf ( "SELECT EXISTS(SELECT 1 from %s WHERE block_number = $1::BIGINT AND block_hash = $2::TEXT LIMIT 1)" , schema . TableHeader . Name )
}
// DetectGapsStm satisfies the sql.Statements interface
func ( db * DB ) DetectGapsStm ( ) string {
return fmt . Sprintf ( "SELECT block_number + 1 AS first_missing, (next_bn - 1) AS last_missing FROM (SELECT block_number, LEAD(block_number) OVER (ORDER BY block_number) AS next_bn FROM %s WHERE block_number >= $1::BIGINT AND block_number <= $2::BIGINT) h WHERE next_bn > block_number + 1" , schema . TableHeader . Name )
2023-06-21 15:49:57 +00:00
}
2023-06-14 12:43:34 +00:00
// InsertHeaderStm satisfies the sql.Statements interface
// Stm == Statement
func ( db * DB ) InsertHeaderStm ( ) string {
return schema . TableHeader . ToInsertStatement ( db . upsert )
}
2023-07-20 02:15:48 +00:00
// SetCanonicalHeaderStm satisfies the sql.Statements interface
// Stm == Statement
func ( db * DB ) SetCanonicalHeaderStm ( ) string {
return fmt . Sprintf ( "UPDATE %s SET canonical = false WHERE block_number = $1::BIGINT AND block_hash <> $2::TEXT AND canonical = true" , schema . TableHeader . Name )
}
2023-06-14 12:43:34 +00:00
// InsertUncleStm satisfies the sql.Statements interface
func ( db * DB ) InsertUncleStm ( ) string {
return schema . TableUncle . ToInsertStatement ( db . upsert )
}
// InsertTxStm satisfies the sql.Statements interface
func ( db * DB ) InsertTxStm ( ) string {
return schema . TableTransaction . ToInsertStatement ( db . upsert )
}
// InsertRctStm satisfies the sql.Statements interface
func ( db * DB ) InsertRctStm ( ) string {
return schema . TableReceipt . ToInsertStatement ( db . upsert )
}
// InsertLogStm satisfies the sql.Statements interface
func ( db * DB ) InsertLogStm ( ) string {
return schema . TableLog . ToInsertStatement ( db . upsert )
}
// InsertStateStm satisfies the sql.Statements interface
func ( db * DB ) InsertStateStm ( ) string {
return schema . TableStateNode . ToInsertStatement ( db . upsert )
}
// InsertStorageStm satisfies the sql.Statements interface
func ( db * DB ) InsertStorageStm ( ) string {
return schema . TableStorageNode . ToInsertStatement ( db . upsert )
}
// InsertIPLDStm satisfies the sql.Statements interface
func ( db * DB ) InsertIPLDStm ( ) string {
return schema . TableIPLDBlock . ToInsertStatement ( db . upsert )
}
// InsertIPLDsStm satisfies the sql.Statements interface
func ( db * DB ) InsertIPLDsStm ( ) string {
return ` INSERT INTO ipld.blocks (block_number, key, data) VALUES (unnest($1::BIGINT[]), unnest($2::TEXT[]), unnest($3::BYTEA[])) ON CONFLICT DO NOTHING `
}