mirror of
https://github.com/semaphoreui/semaphore.git
synced 2024-11-23 12:30:41 +01:00
feat(be): add env, tempalte and inv implementation for bolt
This commit is contained in:
parent
14f2df7910
commit
67acad9c32
@ -163,3 +163,8 @@ var RepositoryObject = ObjectProperties{
|
||||
TemplateColumnName: "repository_id",
|
||||
}
|
||||
|
||||
var TemplateObject = ObjectProperties{
|
||||
TableName: "project__template",
|
||||
SortableColumns: []string{"name"},
|
||||
}
|
||||
|
||||
|
@ -11,14 +11,21 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
||||
type enumerable interface {
|
||||
First() (key []byte, value []byte)
|
||||
Next() (key []byte, value []byte)
|
||||
}
|
||||
|
||||
|
||||
type BoltDb struct {
|
||||
db *bbolt.DB
|
||||
}
|
||||
|
||||
func makeBucketId(obj db.ObjectProperties, ids ...int) []byte {
|
||||
func makeBucketId(props db.ObjectProperties, ids ...int) []byte {
|
||||
n := len(ids)
|
||||
|
||||
id := obj.TableName
|
||||
id := props.TableName
|
||||
for i := 0; i < n; i++ {
|
||||
id += fmt.Sprintf("_%010d", ids[i])
|
||||
}
|
||||
@ -78,15 +85,19 @@ func getFieldNameByTag(t reflect.Type, tag string, value string) (string, error)
|
||||
func sortObjects(objects interface{}, sortBy string, sortInverted bool) error {
|
||||
objectsValue := reflect.ValueOf(objects).Elem()
|
||||
objType := objectsValue.Type().Elem()
|
||||
|
||||
fieldName, err := getFieldNameByTag(objType, "db", sortBy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sort.SliceStable(objectsValue.Interface(), func (i, j int) bool {
|
||||
fieldI := objectsValue.Index(i).FieldByName(fieldName)
|
||||
fieldJ := objectsValue.Index(j).FieldByName(fieldName)
|
||||
switch fieldJ.Kind() {
|
||||
valueI := objectsValue.Index(i).FieldByName(fieldName)
|
||||
valueJ := objectsValue.Index(j).FieldByName(fieldName)
|
||||
|
||||
less := false
|
||||
|
||||
switch valueI.Kind() {
|
||||
case reflect.Int:
|
||||
case reflect.Int8:
|
||||
case reflect.Int16:
|
||||
@ -97,65 +108,72 @@ func sortObjects(objects interface{}, sortBy string, sortInverted bool) error {
|
||||
case reflect.Uint16:
|
||||
case reflect.Uint32:
|
||||
case reflect.Uint64:
|
||||
return fieldI.Int() < fieldJ.Int()
|
||||
less = valueI.Int() < valueJ.Int()
|
||||
case reflect.Float32:
|
||||
case reflect.Float64:
|
||||
return fieldI.Float() < fieldJ.Float()
|
||||
less = valueI.Float() < valueJ.Float()
|
||||
case reflect.String:
|
||||
return fieldI.String() < fieldJ.String()
|
||||
less = valueI.String() < valueJ.String()
|
||||
}
|
||||
return false
|
||||
|
||||
if sortInverted {
|
||||
less = !less
|
||||
}
|
||||
|
||||
return less
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *BoltDb) getObjects(projectID int, props db.ObjectProperties, params db.RetrieveQueryParams, objects interface{}) (err error) {
|
||||
func unmarshalObjects(rawData enumerable, params db.RetrieveQueryParams, objects interface{}) (err error) {
|
||||
objectsValue := reflect.ValueOf(objects).Elem()
|
||||
objType := objectsValue.Type().Elem()
|
||||
|
||||
// Read elements from database
|
||||
err = d.db.View(func(tx *bbolt.Tx) error {
|
||||
i := 0 // current item index
|
||||
n := 0 // number of added items
|
||||
|
||||
b := tx.Bucket(makeBucketId(props, projectID))
|
||||
c := b.Cursor()
|
||||
i := 0 // current item index
|
||||
n := 0 // number of added items
|
||||
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
if i < params.Offset {
|
||||
continue
|
||||
}
|
||||
|
||||
obj := reflect.New(objType).Elem()
|
||||
err2 := json.Unmarshal(v, &obj)
|
||||
if err2 == nil {
|
||||
return err2
|
||||
}
|
||||
|
||||
objectsValue.Set(reflect.Append(objectsValue, obj))
|
||||
|
||||
n++
|
||||
|
||||
if n > params.Count {
|
||||
break
|
||||
}
|
||||
for k, v := rawData.First(); k != nil; k, v = rawData.Next() {
|
||||
if i < params.Offset {
|
||||
continue
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
obj := reflect.New(objType).Elem()
|
||||
err = json.Unmarshal(v, &obj)
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
objectsValue.Set(reflect.Append(objectsValue, obj))
|
||||
|
||||
n++
|
||||
|
||||
if n > params.Count {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Sort elements
|
||||
err = sortObjects(objects, params.SortBy, params.SortInverted)
|
||||
if params.SortBy != "" {
|
||||
err = sortObjects(objects, params.SortBy, params.SortInverted)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (d *BoltDb) getObjects(projectID int, props db.ObjectProperties, params db.RetrieveQueryParams, objects interface{}) error {
|
||||
return d.db.View(func(tx *bbolt.Tx) error {
|
||||
|
||||
b := tx.Bucket(makeBucketId(props, projectID))
|
||||
c := b.Cursor()
|
||||
|
||||
return unmarshalObjects(c, params, objects)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func (d *BoltDb) isObjectInUse(projectID int, props db.ObjectProperties, objectID int) (inUse bool, err error) {
|
||||
err = d.db.View(func(tx *bbolt.Tx) error {
|
||||
@ -190,3 +208,53 @@ func (d *BoltDb) deleteObject(projectID int, props db.ObjectProperties, objectID
|
||||
func (d *BoltDb) deleteObjectSoft(projectID int, props db.ObjectProperties, objectID int) error {
|
||||
return d.deleteObject(projectID, props, objectID)
|
||||
}
|
||||
|
||||
func (d *BoltDb) updateObject(projectID int, props db.ObjectProperties, object interface{}) error {
|
||||
return d.db.Update(func(tx *bbolt.Tx) error {
|
||||
b := tx.Bucket(makeBucketId(props, projectID))
|
||||
if b == nil {
|
||||
return db.ErrNotFound
|
||||
}
|
||||
|
||||
idValue := reflect.ValueOf(object).FieldByName("ID")
|
||||
|
||||
id := []byte(strconv.Itoa(int(idValue.Int())))
|
||||
if b.Get(id) == nil {
|
||||
return db.ErrNotFound
|
||||
}
|
||||
|
||||
str, err := json.Marshal(object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return b.Put(id, str)
|
||||
})
|
||||
}
|
||||
|
||||
func (d *BoltDb) createObject(projectID int, props db.ObjectProperties, object interface{}) (interface{}, error) {
|
||||
err := d.db.Update(func(tx *bbolt.Tx) error {
|
||||
b, err2 := tx.CreateBucketIfNotExists(makeBucketId(props, projectID))
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
|
||||
id, err2 := b.NextSequence()
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
|
||||
idValue := reflect.ValueOf(object).FieldByName("ID")
|
||||
|
||||
idValue.SetInt(int64(id))
|
||||
|
||||
str, err2 := json.Marshal(object)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
|
||||
return b.Put([]byte(strconv.Itoa(int(id))), str)
|
||||
})
|
||||
|
||||
return object, err
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package bolt
|
||||
|
||||
import "github.com/ansible-semaphore/semaphore/db"
|
||||
import (
|
||||
"github.com/ansible-semaphore/semaphore/db"
|
||||
)
|
||||
|
||||
func (d *BoltDb) GetAccessKey(projectID int, accessKeyID int) (db.AccessKey, error) {
|
||||
var key db.AccessKey
|
||||
@ -15,11 +17,12 @@ func (d *BoltDb) GetAccessKeys(projectID int, params db.RetrieveQueryParams) ([]
|
||||
}
|
||||
|
||||
func (d *BoltDb) UpdateAccessKey(key db.AccessKey) error {
|
||||
return nil
|
||||
return d.updateObject(*key.ProjectID, db.AccessKeyObject, key)
|
||||
}
|
||||
|
||||
func (d *BoltDb) CreateAccessKey(key db.AccessKey) (newKey db.AccessKey, err error) {
|
||||
return
|
||||
func (d *BoltDb) CreateAccessKey(key db.AccessKey) (db.AccessKey, error) {
|
||||
newKey, err := d.createObject(*key.ProjectID, db.GlobalAccessKeyObject, key)
|
||||
return newKey.(db.AccessKey), err
|
||||
}
|
||||
|
||||
func (d *BoltDb) DeleteAccessKey(projectID int, accessKeyID int) error {
|
||||
@ -31,24 +34,23 @@ func (d *BoltDb) DeleteAccessKeySoft(projectID int, accessKeyID int) error {
|
||||
}
|
||||
|
||||
|
||||
func (d *BoltDb) GetGlobalAccessKey(accessKeyID int) (db.AccessKey, error) {
|
||||
var key db.AccessKey
|
||||
err := d.getObject(0, db.GlobalAccessKeyObject, accessKeyID, &key)
|
||||
return key, err
|
||||
func (d *BoltDb) GetGlobalAccessKey(accessKeyID int) (key db.AccessKey, err error) {
|
||||
err = d.getObject(0, db.GlobalAccessKeyObject, accessKeyID, &key)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *BoltDb) GetGlobalAccessKeys(params db.RetrieveQueryParams) ([]db.AccessKey, error) {
|
||||
var keys []db.AccessKey
|
||||
err := d.getObjects(0, db.GlobalAccessKeyObject, params, &keys)
|
||||
return keys, err
|
||||
func (d *BoltDb) GetGlobalAccessKeys(params db.RetrieveQueryParams) (keys []db.AccessKey, err error) {
|
||||
err = d.getObjects(0, db.GlobalAccessKeyObject, params, &keys)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *BoltDb) UpdateGlobalAccessKey(key db.AccessKey) error {
|
||||
return nil
|
||||
return d.updateObject(0, db.AccessKeyObject, key)
|
||||
}
|
||||
|
||||
func (d *BoltDb) CreateGlobalAccessKey(key db.AccessKey) (newKey db.AccessKey, err error) {
|
||||
return
|
||||
func (d *BoltDb) CreateGlobalAccessKey(key db.AccessKey) (db.AccessKey, error) {
|
||||
newKey, err := d.createObject(0, db.GlobalAccessKeyObject, key)
|
||||
return newKey.(db.AccessKey), err
|
||||
}
|
||||
|
||||
func (d *BoltDb) DeleteGlobalAccessKey(accessKeyID int) error {
|
||||
|
30
db/bolt/environment.go
Normal file
30
db/bolt/environment.go
Normal file
@ -0,0 +1,30 @@
|
||||
package bolt
|
||||
|
||||
import "github.com/ansible-semaphore/semaphore/db"
|
||||
|
||||
func (d *BoltDb) GetEnvironment(projectID int, environmentID int) (environment db.Environment, err error) {
|
||||
err = d.getObject(projectID, db.EnvironmentObject, environmentID, &environment)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *BoltDb) GetEnvironments(projectID int, params db.RetrieveQueryParams) (environment []db.Environment, err error) {
|
||||
err = d.getObjects(projectID, db.EnvironmentObject, params, &environment)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *BoltDb) UpdateEnvironment(env db.Environment) error {
|
||||
return d.updateObject(env.ProjectID, db.EnvironmentObject, &env)
|
||||
}
|
||||
|
||||
func (d *BoltDb) CreateEnvironment(env db.Environment) (db.Environment, error) {
|
||||
newEnv, err := d.createObject(env.ProjectID, db.EnvironmentObject, env)
|
||||
return newEnv.(db.Environment), err
|
||||
}
|
||||
|
||||
func (d *BoltDb) DeleteEnvironment(projectID int, environmentID int) error {
|
||||
return d.deleteObject(projectID, db.EnvironmentObject, environmentID)
|
||||
}
|
||||
|
||||
func (d *BoltDb) DeleteEnvironmentSoft(projectID int, environmentID int) error {
|
||||
return d.deleteObjectSoft(projectID, db.EnvironmentObject, environmentID)
|
||||
}
|
@ -1,28 +1,12 @@
|
||||
package bolt
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/ansible-semaphore/semaphore/db"
|
||||
"go.etcd.io/bbolt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
||||
func (d *BoltDb) GetInventory(projectID int, inventoryID int) (inventory db.Inventory, err error) {
|
||||
err = d.db.View(func(tx *bbolt.Tx) error {
|
||||
b := tx.Bucket(makeBucketId(db.InventoryObject, projectID))
|
||||
if b == nil {
|
||||
return db.ErrNotFound
|
||||
}
|
||||
|
||||
id := []byte(strconv.Itoa(inventoryID))
|
||||
str := b.Get(id)
|
||||
if str == nil {
|
||||
return db.ErrNotFound
|
||||
}
|
||||
|
||||
return json.Unmarshal(str, &inventory)
|
||||
})
|
||||
err = d.getObject(projectID, db.InventoryObject, inventoryID, &inventory)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
@ -43,76 +27,26 @@ func (d *BoltDb) GetInventory(projectID int, inventoryID int) (inventory db.Inve
|
||||
}
|
||||
|
||||
func (d *BoltDb) GetInventories(projectID int, params db.RetrieveQueryParams) (inventories []db.Inventory, err error) {
|
||||
err = d.db.Update(func(tx *bbolt.Tx) error {
|
||||
b := tx.Bucket(makeBucketId(db.InventoryObject, projectID))
|
||||
if b == nil {
|
||||
return db.ErrNotFound
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return inventories, err
|
||||
}
|
||||
|
||||
func (d *BoltDb) DeleteInventory(projectID int, inventoryID int) error {
|
||||
return d.db.Update(func (tx *bbolt.Tx) error {
|
||||
b := tx.Bucket(makeBucketId(db.InventoryObject, projectID))
|
||||
if b == nil {
|
||||
return db.ErrNotFound
|
||||
}
|
||||
return b.Delete([]byte(strconv.Itoa(inventoryID)))
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (d *BoltDb) DeleteInventorySoft(projectID int, inventoryID int) error {
|
||||
return d.DeleteInventory(projectID, inventoryID)
|
||||
}
|
||||
|
||||
func (d *BoltDb) UpdateInventory(inventory db.Inventory) error {
|
||||
err := d.db.Update(func(tx *bbolt.Tx) error {
|
||||
b := tx.Bucket([]byte("inventory_" + strconv.Itoa(inventory.ProjectID)))
|
||||
if b == nil {
|
||||
return db.ErrNotFound
|
||||
}
|
||||
|
||||
id := []byte(strconv.Itoa(inventory.ID))
|
||||
if b.Get(id) == nil {
|
||||
return db.ErrNotFound
|
||||
}
|
||||
|
||||
str, err2 := json.Marshal(inventory)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
|
||||
return b.Put(id, str)
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *BoltDb) CreateInventory(inventory db.Inventory) (newInventory db.Inventory, err error) {
|
||||
err = d.db.Update(func(tx *bbolt.Tx) error {
|
||||
b, err2 := tx.CreateBucketIfNotExists(makeBucketId(db.InventoryObject, inventory.ProjectID))
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
|
||||
id, _ := b.NextSequence()
|
||||
newInventory = inventory
|
||||
newInventory.ID = int(id)
|
||||
str, err2 := json.Marshal(newInventory)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
|
||||
return b.Put([]byte(strconv.Itoa(newInventory.ID)), str)
|
||||
})
|
||||
|
||||
err = d.getObjects(projectID, db.AccessKeyObject, params, &inventories)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *BoltDb) DeleteInventory(projectID int, inventoryID int) error {
|
||||
return d.deleteObject(projectID, db.InventoryObject, inventoryID)
|
||||
}
|
||||
|
||||
func (d *BoltDb) DeleteInventorySoft(projectID int, inventoryID int) error {
|
||||
return d.deleteObjectSoft(projectID, db.InventoryObject, inventoryID)
|
||||
}
|
||||
|
||||
func (d *BoltDb) UpdateInventory(inventory db.Inventory) error {
|
||||
return d.updateObject(inventory.ProjectID, db.InventoryObject, inventory)
|
||||
}
|
||||
|
||||
func (d *BoltDb) CreateInventory(inventory db.Inventory) (db.Inventory, error) {
|
||||
newInventory, err := d.createObject(inventory.ProjectID, db.InventoryObject, inventory)
|
||||
return newInventory.(db.Inventory), err
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
33
db/bolt/repository.go
Normal file
33
db/bolt/repository.go
Normal file
@ -0,0 +1,33 @@
|
||||
package bolt
|
||||
|
||||
import (
|
||||
"github.com/ansible-semaphore/semaphore/db"
|
||||
)
|
||||
|
||||
func (d *BoltDb) GetRepository(projectID int, repositoryID int) (repository db.Repository, err error) {
|
||||
err = d.getObject(projectID, db.RepositoryObject, repositoryID, &repository)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *BoltDb) GetRepositories(projectID int, params db.RetrieveQueryParams) (repositories []db.Repository, err error) {
|
||||
err = d.getObjects(projectID, db.RepositoryObject, params, &repositories)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *BoltDb) UpdateRepository(repository db.Repository) error {
|
||||
return d.updateObject(repository.ProjectID, db.RepositoryObject, repository)
|
||||
}
|
||||
|
||||
func (d *BoltDb) CreateRepository(repository db.Repository) (db.Repository, error) {
|
||||
newRepo, err := d.createObject(repository.ProjectID, db.RepositoryObject, repository)
|
||||
return newRepo.(db.Repository), err
|
||||
}
|
||||
|
||||
func (d *BoltDb) DeleteRepository(projectID int, repositoryId int) error {
|
||||
return d.deleteObject(projectID, db.RepositoryObject, repositoryId)
|
||||
}
|
||||
|
||||
func (d *BoltDb) DeleteRepositorySoft(projectID int, repositoryId int) error {
|
||||
return d.deleteObjectSoft(projectID, db.RepositoryObject, repositoryId)
|
||||
}
|
||||
|
28
db/bolt/template.go
Normal file
28
db/bolt/template.go
Normal file
@ -0,0 +1,28 @@
|
||||
package bolt
|
||||
|
||||
import (
|
||||
"github.com/ansible-semaphore/semaphore/db"
|
||||
)
|
||||
|
||||
func (d *BoltDb) CreateTemplate(template db.Template) (db.Template, error) {
|
||||
newTemplate, err := d.createObject(template.ProjectID, db.TemplateObject, template)
|
||||
return newTemplate.(db.Template), err
|
||||
}
|
||||
|
||||
func (d *BoltDb) UpdateTemplate(template db.Template) error {
|
||||
return d.updateObject(template.ProjectID, db.TemplateObject, template)
|
||||
}
|
||||
|
||||
func (d *BoltDb) GetTemplates(projectID int, params db.RetrieveQueryParams) (templates []db.Template, err error) {
|
||||
err = d.getObjects(projectID, db.TemplateObject, params, &templates)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *BoltDb) GetTemplate(projectID int, templateID int) (template db.Template, err error) {
|
||||
err = d.getObject(projectID, db.TemplateObject, templateID, &template)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *BoltDb) DeleteTemplate(projectID int, templateID int) error {
|
||||
return d.deleteObject(projectID, db.TemplateObject, templateID)
|
||||
}
|
Loading…
Reference in New Issue
Block a user