From 35073c477671f9afd4e2fd4663a4d31e278e4511 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sat, 27 Sep 2014 13:32:54 -0700 Subject: [PATCH] moved sql-based Blobstore to the database package --- server/blobstore/blobsql/blob.go | 9 ---- server/blobstore/blobsql/blobstore.go | 55 ------------------- server/blobstore/blobsql/const.go | 18 ------- server/blobstore/blobsql/context.go | 11 ---- server/datastore/database/blob.go | 75 ++++++++++++++++++++++++++ server/datastore/database/blob_test.go | 66 +++++++++++++++++++++++ 6 files changed, 141 insertions(+), 93 deletions(-) delete mode 100644 server/blobstore/blobsql/blob.go delete mode 100644 server/blobstore/blobsql/blobstore.go delete mode 100644 server/blobstore/blobsql/const.go delete mode 100644 server/blobstore/blobsql/context.go create mode 100644 server/datastore/database/blob.go create mode 100644 server/datastore/database/blob_test.go diff --git a/server/blobstore/blobsql/blob.go b/server/blobstore/blobsql/blob.go deleted file mode 100644 index 0cd226b1..00000000 --- a/server/blobstore/blobsql/blob.go +++ /dev/null @@ -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" } diff --git a/server/blobstore/blobsql/blobstore.go b/server/blobstore/blobsql/blobstore.go deleted file mode 100644 index 708e2cb9..00000000 --- a/server/blobstore/blobsql/blobstore.go +++ /dev/null @@ -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} -} diff --git a/server/blobstore/blobsql/const.go b/server/blobstore/blobsql/const.go deleted file mode 100644 index d675ecd8..00000000 --- a/server/blobstore/blobsql/const.go +++ /dev/null @@ -1,18 +0,0 @@ -package blobsql - -const ( - tableBlob = "blobs" -) - -const ( - queryBlob = ` - SELECT * - FROM blobs - WHERE blob_path = ?; - ` - - deleteBlob = ` - DELETE FROM blobs - WHERE blob_path = ?; - ` -) diff --git a/server/blobstore/blobsql/context.go b/server/blobstore/blobsql/context.go deleted file mode 100644 index 2d8dc5df..00000000 --- a/server/blobstore/blobsql/context.go +++ /dev/null @@ -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)) -} diff --git a/server/datastore/database/blob.go b/server/datastore/database/blob.go new file mode 100644 index 00000000..87614e81 --- /dev/null +++ b/server/datastore/database/blob.go @@ -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 = ?; +` diff --git a/server/datastore/database/blob_test.go b/server/datastore/database/blob_test.go new file mode 100644 index 00000000..d61427df --- /dev/null +++ b/server/datastore/database/blob_test.go @@ -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() + }) + + }) +}