woodpecker/pkg/store/builtin/blob.go
2015-06-13 17:37:36 -07:00

85 lines
1.8 KiB
Go

package builtin
import (
"bytes"
"database/sql"
"io"
"io/ioutil"
)
type Blob struct {
ID int64
Path string `sql:"unique:ux_blob_path"`
Data []byte
}
type Blobstore struct {
*sql.DB
}
// Del removes an object from the blobstore.
func (db *Blobstore) DelBlob(path string) error {
blob, _ := getBlob(db, rebind(stmtBlobSelectBlobPath), path)
if blob == nil {
return nil
}
_, err := db.Exec(rebind(stmtBlobDelete), blob.ID)
return err
}
// Get retrieves an object from the blobstore.
func (db *Blobstore) GetBlob(path string) ([]byte, error) {
blob, err := getBlob(db, rebind(stmtBlobSelectBlobPath), path)
if err != nil {
return nil, nil
}
return blob.Data, nil
}
// GetBlobReader retrieves an object from the blobstore.
// It is the caller's responsibility to call Close on
// the ReadCloser when finished reading.
func (db *Blobstore) GetBlobReader(path string) (io.ReadCloser, error) {
var blob, err = db.GetBlob(path)
var buf = bytes.NewBuffer(blob)
return ioutil.NopCloser(buf), err
}
// SetBlob inserts an object into the blobstore.
func (db *Blobstore) SetBlob(path string, data []byte) error {
blob, _ := getBlob(db, rebind(stmtBlobSelectBlobPath), path)
if blob == nil {
blob = &Blob{}
}
blob.Path = path
blob.Data = data
if blob.ID == 0 {
return createBlob(db, rebind(stmtBlobInsert), blob)
}
return updateBlob(db, rebind(stmtBlobUpdate), blob)
}
// SetBlobReader inserts an object into the blobstore by
// consuming data from r until EOF.
func (db *Blobstore) SetBlobReader(path string, r io.Reader) error {
var data, _ = ioutil.ReadAll(r)
return db.SetBlob(path, data)
}
func NewBlobstore(db *sql.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 = ?;
`