You've already forked woodpecker
							
							
				mirror of
				https://github.com/woodpecker-ci/woodpecker.git
				synced 2025-10-30 23:27:39 +02:00 
			
		
		
		
	moved sql-based Blobstore to the database package
This commit is contained in:
		
							
								
								
									
										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() | ||||
| 		}) | ||||
|  | ||||
| 	}) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user