moved sql-based Blobstore to the database package
This commit is contained in:
parent
d9db7b9a8d
commit
35073c4776
6 changed files with 141 additions and 93 deletions
|
@ -1,9 +0,0 @@
|
||||||
package blobsql
|
|
||||||
|
|
||||||
type Blob struct {
|
|
||||||
ID int64 `meddler:"blob_id,pk" orm:"column(blob_id);pk;auto"`
|
|
||||||
Path string `meddler:"blob_path" orm:"column(blob_path);size(2000);unique"`
|
|
||||||
Data string `meddler:"blob_data,gobgzip" orm:"column(blob_data);type(text)"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Blob) TableName() string { return "blobs" }
|
|
|
@ -1,55 +0,0 @@
|
||||||
package blobsql
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"github.com/russross/meddler"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Blobstore struct {
|
|
||||||
meddler.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
// Del removes an object from the blobstore.
|
|
||||||
func (b *Blobstore) Del(path string) error {
|
|
||||||
var _, err = b.Exec(deleteBlob, path)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get retrieves an object from the blobstore.
|
|
||||||
func (b *Blobstore) Get(path string) ([]byte, error) {
|
|
||||||
var blob = Blob{}
|
|
||||||
var err = meddler.QueryRow(b, &blob, queryBlob, 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 (b *Blobstore) GetReader(path string) (io.ReadCloser, error) {
|
|
||||||
var blob, err = b.Get(path)
|
|
||||||
var buf = bytes.NewBuffer(blob)
|
|
||||||
return ioutil.NopCloser(buf), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put inserts an object into the blobstore.
|
|
||||||
func (b *Blobstore) Put(path string, data []byte) error {
|
|
||||||
var blob = Blob{}
|
|
||||||
meddler.QueryRow(b, &blob, queryBlob, path)
|
|
||||||
blob.Path = path
|
|
||||||
blob.Data = string(data)
|
|
||||||
return meddler.Save(b, tableBlob, &blob)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PutReader inserts an object into the blobstore by
|
|
||||||
// consuming data from r until EOF.
|
|
||||||
func (b *Blobstore) PutReader(path string, r io.Reader) error {
|
|
||||||
var data, _ = ioutil.ReadAll(r)
|
|
||||||
return b.Put(path, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(db meddler.DB) *Blobstore {
|
|
||||||
return &Blobstore{db}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package blobsql
|
|
||||||
|
|
||||||
const (
|
|
||||||
tableBlob = "blobs"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
queryBlob = `
|
|
||||||
SELECT *
|
|
||||||
FROM blobs
|
|
||||||
WHERE blob_path = ?;
|
|
||||||
`
|
|
||||||
|
|
||||||
deleteBlob = `
|
|
||||||
DELETE FROM blobs
|
|
||||||
WHERE blob_path = ?;
|
|
||||||
`
|
|
||||||
)
|
|
|
@ -1,11 +0,0 @@
|
||||||
package blobsql
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.google.com/p/go.net/context"
|
|
||||||
"github.com/drone/drone/server/blobstore"
|
|
||||||
"github.com/russross/meddler"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewContext(parent context.Context, db meddler.DB) context.Context {
|
|
||||||
return blobstore.NewContext(parent, New(db))
|
|
||||||
}
|
|
75
server/datastore/database/blob.go
Normal file
75
server/datastore/database/blob.go
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
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 = ?;
|
||||||
|
`
|
66
server/datastore/database/blob_test.go
Normal file
66
server/datastore/database/blob_test.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/franela/goblin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBlobstore(t *testing.T) {
|
||||||
|
db := mustConnectTest()
|
||||||
|
bs := NewBlobstore(db)
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
g := goblin.Goblin(t)
|
||||||
|
g.Describe("Blobstore", func() {
|
||||||
|
|
||||||
|
// before each test be sure to purge the package
|
||||||
|
// table data from the database.
|
||||||
|
g.BeforeEach(func() {
|
||||||
|
db.Exec("DELETE FROM blobs")
|
||||||
|
})
|
||||||
|
|
||||||
|
g.It("Should Put a Blob", func() {
|
||||||
|
err := bs.Put("foo", []byte("bar"))
|
||||||
|
g.Assert(err == nil).IsTrue()
|
||||||
|
})
|
||||||
|
|
||||||
|
g.It("Should Put a Blob reader", func() {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
buf.Write([]byte("bar"))
|
||||||
|
err := bs.PutReader("foo", &buf)
|
||||||
|
g.Assert(err == nil).IsTrue()
|
||||||
|
})
|
||||||
|
|
||||||
|
g.It("Should Overwrite a Blob", func() {
|
||||||
|
bs.Put("foo", []byte("bar"))
|
||||||
|
bs.Put("foo", []byte("baz"))
|
||||||
|
blob, err := bs.Get("foo")
|
||||||
|
g.Assert(err == nil).IsTrue()
|
||||||
|
g.Assert(string(blob)).Equal("baz")
|
||||||
|
})
|
||||||
|
|
||||||
|
g.It("Should Get a Blob", func() {
|
||||||
|
bs.Put("foo", []byte("bar"))
|
||||||
|
blob, err := bs.Get("foo")
|
||||||
|
g.Assert(err == nil).IsTrue()
|
||||||
|
g.Assert(string(blob)).Equal("bar")
|
||||||
|
})
|
||||||
|
|
||||||
|
g.It("Should Get a Blob reader", func() {
|
||||||
|
bs.Put("foo", []byte("bar"))
|
||||||
|
r, _ := bs.GetReader("foo")
|
||||||
|
blob, _ := ioutil.ReadAll(r)
|
||||||
|
g.Assert(string(blob)).Equal("bar")
|
||||||
|
})
|
||||||
|
|
||||||
|
g.It("Should Del a Blob", func() {
|
||||||
|
bs.Put("foo", []byte("bar"))
|
||||||
|
err := bs.Del("foo")
|
||||||
|
g.Assert(err == nil).IsTrue()
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue