Example #1
0
func (self *SQLDB) Refresh(chainManager *core.ChainManager) {
	fromBlock, err := getLastBlockNumber(self.db)
	if err != nil {
		glog.V(logger.Error).Infoln("Error fetching last SQL block number", err)
		return
	}

	toBlock := chainManager.CurrentBlock().Number().Uint64()

	if fromBlock >= toBlock {
		// sanity check TODO: redo the whole SQL DB in this case!
		if fromBlock > toBlock {
			glog.V(logger.Error).Infoln("SQL DB ahead of chain, recreating")
			self.Close()
			os.Remove(self.fn)
			self.db, err = Init(self.fn)
			if err != nil {
				glog.V(logger.Error).Infoln("SQL DB Reinit:", err)
				return
			}
		} else {
			return
		}
	}

	tx, err := self.db.Begin()
	if err != nil {
		glog.V(logger.Error).Infoln("SQL DB Begin:", err)
		return
	}

	stmtBlock, err := tx.Prepare(`insert or replace into shift_blocks(number, hash) values(?, ?)`)
	if err != nil {
		glog.V(logger.Error).Infoln("SQL DB:", err)
		return
	}
	defer stmtBlock.Close()

	stmtTrans, err := tx.Prepare(`insert or replace into shift_transactions(hash, blocknumber, sender, receiver) values(?, ?, ?, ?)`)
	if err != nil {
		glog.V(logger.Error).Infoln("SQL DB:", err)
		return
	}
	defer stmtTrans.Close()

	glog.V(logger.Info).Infoln("SQL DB refreshing between blocks:", fromBlock, toBlock)
	for i := fromBlock + 1; i <= toBlock; i++ {
		block := chainManager.GetBlockByNumber(i)
		// block
		_, err = stmtBlock.Exec(i, block.Hash().Hex())
		if err != nil {
			glog.V(logger.Error).Infoln("SQL DB:", err)
			tx.Rollback()
			return
		}
		// transactions

		for _, trans := range block.Transactions() {
			sender, err := trans.From()
			if err != nil {
				glog.V(logger.Error).Infoln("SQL DB:", err)
				continue
			}
			senderHex := sender.Hex()
			receiver := trans.To()
			receiverHex := ""
			if receiver != nil {
				receiverHex = receiver.Hex()
			}
			_, err = stmtTrans.Exec(trans.Hash().Hex(), i, senderHex, receiverHex)
			if err != nil {
				glog.V(logger.Error).Infoln("SQL DB:", err)
				tx.Rollback()
				return
			}
		}
	}
	tx.Commit()
}