mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
* serverless sqldb use same env for test config as normal * rip boltdb implementation of controller backend out it was replaced by postgres and no longer works properly. This involved migrating a number of tests which only worked with boltdb, which exposed several ways in which the postgres implementation had slightly different behavior from the bolt one: 1. ordering of results in some cases, and 2. (more importantly) erroring when a record to delete was not found. The bolt implementation silently ignored it when things to delete weren't found, so we make some changes to match that behavior. Also stopped propagating CreatedAt and UpdatedAt from DB tables into dax types. These were breaking existing tests. Perhaps it would be better to actually use them, but for now they will only exist at the DB level. This change set also moves the insertion of the directive_versions record out of migrations and into the startup/connection code. Having this in the migrations was a bit ugly because you couldn't just truncate all the tables and have everything work from scratch. Inserting it during startup is fairly innocuous, and will just continue on if it already exists. * update directive_version test I changed the initial value to 0 so that the first version that gets sent out is 1
116 lines
2.7 KiB
Go
116 lines
2.7 KiB
Go
package sqldb
|
|
|
|
import (
|
|
"github.com/featurebasedb/featurebase/v3/dax"
|
|
"github.com/featurebasedb/featurebase/v3/dax/controller"
|
|
"github.com/featurebasedb/featurebase/v3/dax/models"
|
|
"github.com/featurebasedb/featurebase/v3/logger"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
var _ controller.NodeService = (*nodeService)(nil)
|
|
|
|
func NewNodeService(log logger.Logger) *nodeService {
|
|
if log == nil {
|
|
log = logger.NopLogger
|
|
}
|
|
return &nodeService{
|
|
log: log,
|
|
}
|
|
}
|
|
|
|
type nodeService struct {
|
|
log logger.Logger
|
|
}
|
|
|
|
func (n *nodeService) CreateNode(tx dax.Transaction, addr dax.Address, node *dax.Node) error {
|
|
dt, ok := tx.(*DaxTransaction)
|
|
if !ok {
|
|
return dax.NewErrInvalidTransaction("*sqldb.DaxTransaction")
|
|
}
|
|
|
|
mnode := &models.Node{Address: node.Address}
|
|
err := dt.C.Create(mnode)
|
|
if err != nil {
|
|
return errors.Wrap(err, "creating node")
|
|
}
|
|
|
|
nodeRoles := make(models.NodeRoles, len(node.RoleTypes))
|
|
mnode.NodeRoles = nodeRoles
|
|
for i, rt := range node.RoleTypes {
|
|
mnode.NodeRoles[i] = models.NodeRole{
|
|
NodeID: mnode.ID,
|
|
Role: rt,
|
|
}
|
|
}
|
|
err = dt.C.Create(&(mnode.NodeRoles))
|
|
if err != nil {
|
|
return errors.Wrap(err, "creating node roles")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (n *nodeService) ReadNode(tx dax.Transaction, addr dax.Address) (*dax.Node, error) {
|
|
dt, ok := tx.(*DaxTransaction)
|
|
if !ok {
|
|
return nil, dax.NewErrInvalidTransaction("*sqldb.DaxTransaction")
|
|
}
|
|
|
|
node := &models.Node{}
|
|
err := dt.C.Eager().Where("address = ?", addr).First(node)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "getting node")
|
|
}
|
|
|
|
roleTypes := make([]dax.RoleType, len(node.NodeRoles))
|
|
for i, nr := range node.NodeRoles {
|
|
roleTypes[i] = nr.Role
|
|
}
|
|
|
|
return &dax.Node{
|
|
Address: node.Address,
|
|
RoleTypes: roleTypes,
|
|
}, nil
|
|
}
|
|
|
|
func (n *nodeService) DeleteNode(tx dax.Transaction, addr dax.Address) error {
|
|
dt, ok := tx.(*DaxTransaction)
|
|
if !ok {
|
|
return dax.NewErrInvalidTransaction("*sqldb.DaxTransaction")
|
|
}
|
|
|
|
node := &models.Node{}
|
|
err := dt.C.Eager().Where("address = ?", addr).First(node)
|
|
if isNoRowsError(err) {
|
|
return nil
|
|
} else if err != nil {
|
|
return errors.Wrap(err, "finding node")
|
|
}
|
|
|
|
err = dt.C.Destroy(node)
|
|
return errors.Wrap(err, "destroying node")
|
|
}
|
|
|
|
func (n *nodeService) Nodes(tx dax.Transaction) ([]*dax.Node, error) {
|
|
dt, ok := tx.(*DaxTransaction)
|
|
if !ok {
|
|
return nil, dax.NewErrInvalidTransaction("*sqldb.DaxTransaction")
|
|
}
|
|
|
|
nodes := []*models.Node{}
|
|
dt.C.Eager().Order("address asc").All(&nodes)
|
|
|
|
ret := make([]*dax.Node, len(nodes))
|
|
for i, node := range nodes {
|
|
ret[i] = &dax.Node{
|
|
Address: node.Address,
|
|
RoleTypes: make([]dax.RoleType, len(node.NodeRoles)),
|
|
}
|
|
for j, nr := range node.NodeRoles {
|
|
ret[i].RoleTypes[j] = nr.Role
|
|
}
|
|
}
|
|
|
|
return ret, nil
|
|
}
|