// Del deletes the object from the bucket func (m master) Del(owner s3intf.Owner, bucket, object string) (err error) { m.Lock() o, ok := m.owners[owner.ID()] m.Unlock() if !ok { return errors.New("cannot find owner " + owner.ID()) } o.Lock() b, ok := o.buckets[bucket] o.Unlock() if !ok { return errors.New("cannot find bucket " + bucket) } if err = b.db.BeginTransaction(); err != nil { return fmt.Errorf("cannot start transaction: %s", err) } defer func() { if err != nil { b.db.Rollback() } }() val, e := b.db.Extract(nil, []byte(object)) if e != nil { err = fmt.Errorf("cannot get %s object: %s", object, e) return } if val == nil { err = s3intf.NotFound return } vi := new(weedutils.ValInfo) if err = vi.Decode(val); err != nil { err = fmt.Errorf("error deserializing %s: %s", val, err) return } if err = m.wm.Delete(vi.Fid); err != nil { return } err = nil return b.db.Commit() }
// Get retrieves an object from the bucket func (m master) Get(owner s3intf.Owner, bucket, object string) ( filename, media string, body io.ReadCloser, size int64, md5 []byte, err error) { m.Lock() o, ok := m.owners[owner.ID()] m.Unlock() if !ok { err = errors.New("cannot find owner " + owner.ID()) return } o.Lock() b, ok := o.buckets[bucket] o.Unlock() if !ok { err = errors.New("cannot find bucket " + bucket) return } val, e := b.db.Get(nil, []byte(object)) if e != nil { err = fmt.Errorf("cannot get %s object: %s", object, e) return } if val == nil { err = s3intf.NotFound return } vi := new(weedutils.ValInfo) if err = vi.Decode(val); err != nil { err = fmt.Errorf("error deserializing %s: %s", val, err) return } filename, media, size, md5 = vi.Filename, vi.ContentType, vi.Size, vi.MD5 body, err = m.wm.Download(vi.Fid) return }
func dumpBucket(w io.Writer, db *kv.DB) (err error) { //log.Printf("dumping %s", db) io.WriteString(w, `{"name": "`+db.Name()+`", "records": [`) enc := json.NewEncoder(w) enum, e := db.SeekFirst() if e != nil { if e != io.EOF { err = e log.Printf("error getting first: %s", err) } return } vi := new(weedutils.ValInfo) for { k, v, err := enum.Next() if err != nil { if err != io.EOF { log.Printf("error getting next: %s", err) } break } if err = vi.Decode(v); err != nil { log.Printf("error decoding %s: %s", v, err) continue } fmt.Fprintf(w, `{"object": %q, "value": `, k) if err = enc.Encode(vi); err != nil { log.Printf("error printing %v to json: %s", vi, err) continue } io.WriteString(w, "},\n") } io.WriteString(w, "]},\n") io.WriteString(w, "]},\n") return nil }
// List lists a bucket, all objects Key starts with prefix, delimiter segments // Key, thus the returned commonprefixes (think a generalized filepath // structure, where / is the delimiter, a commonprefix is a subdir) func (m master) List(owner s3intf.Owner, bucket, prefix, delimiter, marker string, limit, skip int) ( objects []s3intf.Object, commonprefixes []string, truncated bool, err error) { m.Lock() o, ok := m.owners[owner.ID()] if !ok { m.Unlock() err = fmt.Errorf("unknown owner %s", owner.ID()) return } o.Lock() b, ok := o.buckets[bucket] o.Unlock() m.Unlock() if !ok { err = fmt.Errorf("unknown bucket %s", bucket) return } err = nil enum, e := b.db.SeekFirst() if e != nil { if e == io.EOF { //empty return } err = fmt.Errorf("error getting first: %s", e) return } var ( key, val []byte vi = new(weedutils.ValInfo) etag string ) objects = make([]s3intf.Object, 0, 64) f := s3intf.NewListFilter(prefix, delimiter, marker, limit, skip) for { if key, val, e = enum.Next(); e != nil { if e == io.EOF { break } err = fmt.Errorf("error seeking next: %s", e) return } //log.Printf("key=%q", key) if ok, e = f.Check(string(key)); e != nil { if e == io.EOF { break } err = fmt.Errorf("error checking %s: %s", key, e) return } else if ok { if err = vi.Decode(val); err != nil { return } if vi.MD5 != nil && len(vi.MD5) == 16 { etag = hex.EncodeToString(vi.MD5) } else { etag = "" } objects = append(objects, s3intf.Object{Key: string(key), Owner: owner, ETag: etag, LastModified: vi.Created, Size: vi.Size}) } } commonprefixes, truncated = f.Result() return }