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() }