package database import ( "bytes" "io" "io/ioutil" "github.com/russross/meddler" ) type Blob struct { ID int64 `meddler:"blob_id,pk"` Path string `meddler:"blob_path"` Data string `meddler:"blob_data,gobgzip"` } type Blobstore struct { meddler.DB } // Del removes an object from the blobstore. func (db *Blobstore) Del(path string) error { var _, err = db.Exec(rebind(blobDeleteStmt), path) return err } // Get retrieves an object from the blobstore. func (db *Blobstore) Get(path string) ([]byte, error) { var blob = Blob{} var err = meddler.QueryRow(db, &blob, rebind(blobQuery), path) return []byte(blob.Data), err } // GetReader retrieves an object from the blobstore. // It is the caller's responsibility to call Close on // the ReadCloser when finished reading. func (db *Blobstore) GetReader(path string) (io.ReadCloser, error) { var blob, err = db.Get(path) var buf = bytes.NewBuffer(blob) return ioutil.NopCloser(buf), err } // Put inserts an object into the blobstore. func (db *Blobstore) Put(path string, data []byte) error { var blob = Blob{} meddler.QueryRow(db, &blob, rebind(blobQuery), path) blob.Path = path blob.Data = string(data) return meddler.Save(db, blobTable, &blob) } // PutReader inserts an object into the blobstore by // consuming data from r until EOF. func (db *Blobstore) PutReader(path string, r io.Reader) error { var data, _ = ioutil.ReadAll(r) return db.Put(path, data) } func NewBlobstore(db meddler.DB) *Blobstore { return &Blobstore{db} } // Blob table name in database. const blobTable = "blobs" const blobQuery = ` SELECT * FROM blobs WHERE blob_path = ?; ` const blobDeleteStmt = ` DELETE FROM blobs WHERE blob_path = ?; `