Example #1
0
// Saves the node database into the DHT. Call this periodically or just before stopping the DHT.
// The current Node ID and port number are also saved.
func (ds *DHTStorage) SaveDHT(d *dht.DHT) error {
	db, err := ds.getDB()
	if err != nil {
		return err
	}

	defer db.Close()
	now := time.Now()

	err = ds.createTablesWith(db)
	if err != nil {
		return err
	}

	tx, err := db.Begin()
	if err != nil {
		return err
	}

	_, err = tx.Exec(`UPDATE dht_routers SET old=1;`)
	if err != nil {
		return err
	}

	err = d.VisitNodes(func(addr string, nodeID []byte) error {
		_, err := tx.Exec(`INSERT OR IGNORE INTO dht_routers
      (hostname,first_seen,old) VALUES (?,?,0);`,
			addr, now)
		if err != nil {
			return err
		}

		_, err = tx.Exec(`UPDATE dht_routers SET node_id=?, last_seen=?, old=0 WHERE hostname=?;`,
			hex.EncodeToString(nodeID), now, addr)
		if err != nil {
			return err
		}

		return nil
	})

	if err != nil {
		return err
	}

	_, err = tx.Exec(`DELETE FROM dht_routers WHERE old=1 AND last_seen < date('now','-2 hours');`)
	if err != nil {
		return err
	}

	_, err = tx.Exec(`UPDATE dht_routers SET first_seen=? WHERE first_seen IS NULL`, time.Now())

	if err != nil {
		return err
	}

	_, err = tx.Exec(`INSERT OR REPLACE INTO dht_settings (key,value) VALUES ('port',?)`, d.Port())
	if err != nil {
		return err
	}

	tx.Commit()
	return nil
}