// 'Writes' an object, this means deleting it (and associated data) if it's dead func (this *DataMgr) writeObj(obj *DataObj) { //this.Log.Printf("Writing object: %v", obj) if len(obj.Tracking) == 0 && obj.Holds == 0 { if obj.State == DSLocal { name := path.Join(this.dir, obj.Key) os.Remove(name) } //this.Log.Printf("Deleting") this.Db.Exec("DELETE FROM Blob WHERE Key = ?", obj.Key) } else { //this.Log.Printf("Deleting and Storing") this.Db.Exec("DELETE FROM Blob WHERE Key = ?", obj.Key) data, err := transfer.EncodeBytes(obj) if err != nil { panic(err) } //this.Log.Printf("Putting data as: %v", data) this.Db.Exec("INSERT INTO Blob (key, needs_download, data) VALUES (?, ?, ?)", obj.Key, obj.State == DSReady && !obj.Downloading, data) } }
// Reads from io.Reader and generates a new object, put it to the meta-data layer func (this *DataMgr) PutData(topic string, key string, writer *crypto.SecretIdentity, stream io.Reader) error { this.Log.Printf("Putting data: %s, %s", topic, key) // Write the object to disk tmppath := path.Join(this.incoming, crypto.RandomString()) file, err := os.Create(tmppath) if err != nil { return err } hasher := crypto.NewHasher() both := io.MultiWriter(file, hasher) _, err = io.Copy(both, stream) if err != nil { _ = os.Remove(tmppath) // Ignore errors return err } digest := hasher.Finalize() okey := digest.String() // Add info to DB this.lock.Lock() obj := this.getObj(okey) obj.newFile(tmppath) obj.Holds++ this.writeObj(obj) this.lock.Unlock() // Put to meta-data layer data, _ := transfer.EncodeBytes(digest) err = this.MetaMgr.Put(topic, writer, key, data) // Remove hold this.lock.Lock() obj = this.getObj(okey) obj.Holds-- this.writeObj(obj) this.lock.Unlock() return err }