creatorupdatordeprecate

This commit is contained in:
Michael McGuinness
2025-01-03 13:41:07 +00:00
parent 0ac156f0e1
commit 788b21594c
36 changed files with 545 additions and 226 deletions
-11
View File
@@ -1,11 +0,0 @@
# https://taskfile.dev
version: '3'
includes:
lib:
taskfile: scripts/Taskfile.yml
flatten: true
vars:
IMAGE_NAME: queryorchestration
COVERAGE_THRESHOLD: 80
+8 -7
View File
@@ -3,6 +3,7 @@ package controllers
import (
serviceinterfaces "queryorchestration/api/serviceInterfaces"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
)
func ParseQuery(query *query.Query) *serviceinterfaces.Query {
@@ -19,24 +20,24 @@ func ParseQuery(query *query.Query) *serviceinterfaces.Query {
}
}
func ParseQueryType(qType query.Type) serviceinterfaces.QueryType {
func ParseQueryType(qType queryprocessor.Type) serviceinterfaces.QueryType {
switch qType {
case query.TypeJsonExtractor:
case queryprocessor.TypeJsonExtractor:
return serviceinterfaces.QueryType_QUERY_TYPE_JSON_EXTRACTOR
case query.TypeContextFull:
case queryprocessor.TypeContextFull:
return serviceinterfaces.QueryType_QUERY_TYPE_CONTEXT_FULL
default:
return serviceinterfaces.QueryType_QUERY_TYPE_UNSPECIFIED
}
}
func ParseSpecQueryType(qType serviceinterfaces.QueryType) query.Type {
func ParseSpecQueryType(qType serviceinterfaces.QueryType) queryprocessor.Type {
switch qType {
case serviceinterfaces.QueryType_QUERY_TYPE_JSON_EXTRACTOR:
return query.TypeJsonExtractor
return queryprocessor.TypeJsonExtractor
case serviceinterfaces.QueryType_QUERY_TYPE_CONTEXT_FULL:
return query.TypeContextFull
return queryprocessor.TypeContextFull
default:
return query.TypeContextFull
return queryprocessor.TypeContextFull
}
}
+8 -6
View File
@@ -2,8 +2,10 @@ package controllers
import (
"context"
"queryorchestration/api/grpc/spec"
serviceinterfaces "queryorchestration/api/serviceInterfaces"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
@@ -25,9 +27,9 @@ func NewQueryController(querySvc query.Service, validator *validator.Validate) *
}
func (s *QueryController) List(ctx context.Context, req *serviceinterfaces.QueryFilter) (*serviceinterfaces.Queries, error) {
types := make([]query.Type, len(req.GetTypes()))
types := make([]queryprocessor.Type, len(req.GetTypes()))
for index, t := range req.GetTypes() {
types[index] = query.Type(ParseSpecQueryType(t))
types[index] = queryprocessor.Type(ParseSpecQueryType(t))
}
filters := query.ListFilters{
@@ -74,7 +76,7 @@ func (s *QueryController) Create(ctx context.Context, req *serviceinterfaces.Que
requiredQueryIDs[index] = parsedID
}
id, err := s.query.Create(ctx, query.Create{
id, err := s.query.Create(ctx, &queryprocessor.Create{
Type: ParseSpecQueryType(req.GetType()),
RequiredQueryIDs: requiredQueryIDs,
})
@@ -93,7 +95,7 @@ func (s *QueryController) Update(ctx context.Context, req *serviceinterfaces.Que
return nil, err
}
err = s.query.Update(ctx, query.Update{
err = s.query.Update(ctx, &queryprocessor.Update{
ID: id,
})
if err != nil {
@@ -103,13 +105,13 @@ func (s *QueryController) Update(ctx context.Context, req *serviceinterfaces.Que
return &emptypb.Empty{}, nil
}
func (s *QueryController) Remove(ctx context.Context, req *serviceinterfaces.IdMessage) (*emptypb.Empty, error) {
func (s *QueryController) Deprecate(ctx context.Context, req *spec.IdMessage) (*emptypb.Empty, error) {
id, err := uuid.Parse(req.GetId())
if err != nil {
return nil, err
}
err = s.query.Remove(ctx, id)
err = s.query.Deprecate(ctx, id)
if err != nil {
return nil, err
}
Submodule api/serviceInterfaces updated: c41bce6522...e3d7e63a27
@@ -0,0 +1 @@
DROP TABLE queryDeprecations;
@@ -0,0 +1,8 @@
CREATE TABLE queryDeprecations (
id uuid primary key DEFAULT gen_random_uuid(),
queryId uuid not null,
time timestamp not null DEFAULT NOW(),
removedAt timestamp,
foreign key (queryId) references queries(id),
unique (queryId, removedAt)
);
+4 -1
View File
@@ -1,5 +1,8 @@
-- name: GetCollectorQueries :many
SELECT collectorId, queryId, type, requiredQueryId, queryVersion FROM collectorQueryDependencyTree WHERE collectorId = $1;
SELECT collectorId, queryId, type, queryVersion, ARRAY_AGG(requiredQueryId) AS requiredIds
FROM collectorQueryDependencyTree
WHERE collectorId = $1
GROUP BY queryId, collectorId, type, queryVersion;
-- name: GetCollectorFromJobID :one
SELECT id, jobId, minCleanVersion, minTextVersion FROM collectors WHERE jobId = $1 LIMIT 1;
+11
View File
@@ -1,6 +1,17 @@
-- name: GetQueryConfig :one
SELECT id, config FROM queryConfigs where queryId = $1 and addedVersion >= $2 and COALESCE(removedVersion, $2 - 1) < $2;
-- name: GetQueryType :one
SELECT type FROM queries where id = $1;
-- name: DeprecateQuery :exec
INSERT INTO queryDeprecations (queryId) VALUES ($1) RETURNING id;
-- name: IsQueryDeprecated :one
SELECT EXISTS (
SELECT 1 FROM queryDeprecations where queryId = $1 and removedAt is not null
);
-- name: GetQuery :one
SELECT q.id, q.type, q.activeVersion, c.config, ARRAY_AGG(r.requiredQueryId) AS requiredIds
FROM queries AS q
+32
View File
@@ -0,0 +1,32 @@
package contextfull
import (
"context"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/queryProcessor"
"github.com/google/uuid"
)
type Creator struct {
db *repository.Queries
}
func NewCreator(db *repository.Queries) Creator {
return Creator{db}
}
func (s Creator) Validate(ctx context.Context, entity *queryprocessor.Create) error {
// TODO
return nil
}
func (s Creator) Create(ctx context.Context, entity *queryprocessor.Create) (uuid.UUID, error) {
err := s.Validate(ctx, entity)
if err != nil {
return uuid.Nil, err
}
// TODO
return uuid.Nil, nil
}
+5 -4
View File
@@ -3,21 +3,22 @@ package contextfull
import (
"context"
"fmt"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
"queryorchestration/internal/result"
)
type Extractor struct {
}
func New() *Extractor {
return &Extractor{}
func NewExtractor() Extractor {
return Extractor{}
}
func (e *Extractor) Process(ctx context.Context, query query.QueryRow, values *[]result.Value) (string, error) {
func (e Extractor) Process(ctx context.Context, query queryprocessor.Query, values *[]result.Value) (string, error) {
if len(*values) > 0 {
return "", fmt.Errorf("no requirements expected")
}
// TODO
return "", nil
}
+30
View File
@@ -0,0 +1,30 @@
package contextfull
import (
"context"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/queryProcessor"
)
type Updator struct {
db *repository.Queries
}
func NewUpdator(db *repository.Queries) Updator {
return Updator{db}
}
func (s Updator) Validate(ctx context.Context, entity *queryprocessor.Update) error {
// TODO
return nil
}
func (s Updator) Update(ctx context.Context, entity *queryprocessor.Update) error {
err := s.Validate(ctx, entity)
if err != nil {
return err
}
// TODO
return nil
}
+10 -7
View File
@@ -35,15 +35,18 @@ func (q *Queries) GetCollectorFromJobID(ctx context.Context, jobid pgtype.UUID)
}
const getCollectorQueries = `-- name: GetCollectorQueries :many
SELECT collectorId, queryId, type, requiredQueryId, queryVersion FROM collectorQueryDependencyTree WHERE collectorId = $1
SELECT collectorId, queryId, type, queryVersion, ARRAY_AGG(requiredQueryId) AS requiredIds
FROM collectorQueryDependencyTree
WHERE collectorId = $1
GROUP BY queryId, collectorId, type, queryVersion
`
type GetCollectorQueriesRow struct {
Collectorid pgtype.UUID
Queryid pgtype.UUID
Type NullQuerytype
Requiredqueryid pgtype.UUID
Queryversion pgtype.Int4
Collectorid pgtype.UUID
Queryid pgtype.UUID
Type NullQuerytype
Queryversion pgtype.Int4
Requiredids []pgtype.UUID
}
func (q *Queries) GetCollectorQueries(ctx context.Context, collectorid pgtype.UUID) ([]GetCollectorQueriesRow, error) {
@@ -59,8 +62,8 @@ func (q *Queries) GetCollectorQueries(ctx context.Context, collectorid pgtype.UU
&i.Collectorid,
&i.Queryid,
&i.Type,
&i.Requiredqueryid,
&i.Queryversion,
&i.Requiredids,
); err != nil {
return nil, err
}
+7
View File
@@ -107,6 +107,13 @@ type Queryconfig struct {
Removedversion pgtype.Int4
}
type Querydeprecation struct {
ID pgtype.UUID
Queryid pgtype.UUID
Time pgtype.Timestamp
Removedat pgtype.Timestamp
}
type Requiredquery struct {
ID pgtype.UUID
Queryid pgtype.UUID
+33
View File
@@ -11,6 +11,15 @@ import (
"github.com/jackc/pgx/v5/pgtype"
)
const deprecateQuery = `-- name: DeprecateQuery :exec
INSERT INTO queryDeprecations (queryId) VALUES ($1) RETURNING id
`
func (q *Queries) DeprecateQuery(ctx context.Context, queryid pgtype.UUID) error {
_, err := q.db.Exec(ctx, deprecateQuery, queryid)
return err
}
const getQuery = `-- name: GetQuery :one
SELECT q.id, q.type, q.activeVersion, c.config, ARRAY_AGG(r.requiredQueryId) AS requiredIds
FROM queries AS q
@@ -65,3 +74,27 @@ func (q *Queries) GetQueryConfig(ctx context.Context, arg GetQueryConfigParams)
err := row.Scan(&i.ID, &i.Config)
return i, err
}
const getQueryType = `-- name: GetQueryType :one
SELECT type FROM queries where id = $1
`
func (q *Queries) GetQueryType(ctx context.Context, id pgtype.UUID) (Querytype, error) {
row := q.db.QueryRow(ctx, getQueryType, id)
var type_ Querytype
err := row.Scan(&type_)
return type_, err
}
const isQueryDeprecated = `-- name: IsQueryDeprecated :one
SELECT EXISTS (
SELECT 1 FROM queryDeprecations where queryId = $1 and removedAt is not null
)
`
func (q *Queries) IsQueryDeprecated(ctx context.Context, queryid pgtype.UUID) (bool, error) {
row := q.db.QueryRow(ctx, isQueryDeprecated, queryid)
var exists bool
err := row.Scan(&exists)
return exists, err
}
+32
View File
@@ -0,0 +1,32 @@
package jsonextractor
import (
"context"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/queryProcessor"
"github.com/google/uuid"
)
type Creator struct {
db *repository.Queries
}
func NewCreator(db *repository.Queries) Creator {
return Creator{db}
}
func (s Creator) Validate(ctx context.Context, entity *queryprocessor.Create) error {
// TODO
return nil
}
func (s Creator) Create(ctx context.Context, entity *queryprocessor.Create) (uuid.UUID, error) {
err := s.Validate(ctx, entity)
if err != nil {
return uuid.Nil, err
}
// TODO
return uuid.Nil, nil
}
+4 -4
View File
@@ -6,7 +6,7 @@ import (
"fmt"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
"queryorchestration/internal/result"
"github.com/tidwall/gjson"
@@ -20,11 +20,11 @@ type Config struct {
Path string `json:"path"`
}
func New(db *repository.Queries) *Extractor {
return &Extractor{db}
func NewExtractor(db *repository.Queries) Extractor {
return Extractor{db}
}
func (e *Extractor) Process(ctx context.Context, query query.QueryRow, values *[]result.Value) (string, error) {
func (e Extractor) Process(ctx context.Context, query queryprocessor.Query, values *[]result.Value) (string, error) {
if len(*values) != 1 {
return "", fmt.Errorf("JSON Extraction requires 1 result")
}
+30
View File
@@ -0,0 +1,30 @@
package jsonextractor
import (
"context"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/queryProcessor"
)
type Updator struct {
db *repository.Queries
}
func NewUpdator(db *repository.Queries) Updator {
return Updator{db}
}
func (s Updator) Validate(ctx context.Context, entity *queryprocessor.Update) error {
// TODO
return nil
}
func (s Updator) Update(ctx context.Context, entity *queryprocessor.Update) error {
err := s.Validate(ctx, entity)
if err != nil {
return err
}
// TODO
return nil
}
+36
View File
@@ -0,0 +1,36 @@
package query
import (
"context"
"fmt"
contextfull "queryorchestration/internal/contextFull"
jsonextractor "queryorchestration/internal/jsonExtractor"
queryprocessor "queryorchestration/internal/queryProcessor"
"github.com/google/uuid"
)
func (s *Service) Create(ctx context.Context, entity *queryprocessor.Create) (uuid.UUID, error) {
validator, err := s.getCreator(entity.Type)
if err != nil {
return uuid.Nil, err
}
id, err := validator.Create(ctx, entity)
if err != nil {
return uuid.Nil, err
}
return id, nil
}
func (s *Service) getCreator(qType queryprocessor.Type) (queryprocessor.Creator, error) {
switch qType {
case queryprocessor.TypeJsonExtractor:
return jsonextractor.NewCreator(s.db), nil
case queryprocessor.TypeContextFull:
return contextfull.NewCreator(s.db), nil
default:
return nil, fmt.Errorf("attempting to process invalid query type")
}
}
+26
View File
@@ -0,0 +1,26 @@
package query
import (
"context"
"queryorchestration/internal/database"
"github.com/google/uuid"
)
func (s *Service) Deprecate(ctx context.Context, id uuid.UUID) error {
dbId := database.MustToDBUUID(id)
exists, err := s.db.IsQueryDeprecated(ctx, dbId)
if err != nil {
return err
} else if exists {
return nil
}
err = s.db.DeprecateQuery(ctx, dbId)
if err != nil {
return err
}
return nil
}
+10
View File
@@ -0,0 +1,10 @@
package query
import (
"context"
)
func (s *Service) List(ctx context.Context, filters ListFilters) (*[]Query, error) {
// TODO
return nil, nil
}
+4 -54
View File
@@ -4,54 +4,27 @@ import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/result"
queryprocessor "queryorchestration/internal/queryProcessor"
"github.com/google/uuid"
)
type Type int
const (
TypeJsonExtractor = iota
TypeContextFull
)
type QueryRow struct {
ID uuid.UUID
Type Type
RequiredQueryID uuid.UUID
Version int32
}
type Query struct {
ID uuid.UUID
Type Type
Type queryprocessor.Type
RequiredQueryIDs []uuid.UUID
Version int32
Config interface{}
}
type ListFilters struct {
Types []Type
}
type Create struct {
Type Type
RequiredQueryIDs []uuid.UUID
}
type Update struct {
ID uuid.UUID
Types []queryprocessor.Type
}
type Test struct {
ID uuid.UUID
}
type Processor interface {
Process(ctx context.Context, query QueryRow, values *[]result.Value) (string, error)
}
type Service struct {
db *repository.Queries
}
@@ -66,7 +39,7 @@ func (s *Service) Get(ctx context.Context, id uuid.UUID) (*Query, error) {
return nil, err
}
queryType, err := ParseDBType(query.Type)
queryType, err := queryprocessor.ParseDBType(query.Type)
if err != nil {
return nil, err
}
@@ -84,26 +57,3 @@ func (s *Service) Get(ctx context.Context, id uuid.UUID) (*Query, error) {
Config: string(query.Config),
}, nil
}
func (s *Service) List(ctx context.Context, filters ListFilters) (*[]Query, error) {
return nil, nil
}
func (s *Service) Create(ctx context.Context, entity Create) (uuid.UUID, error) {
return uuid.Nil, nil
}
func (s *Service) Update(ctx context.Context, entity Update) error {
return nil
}
func (s *Service) Remove(ctx context.Context, id uuid.UUID) error {
return nil
}
func (s *Service) Test(ctx context.Context, filters Test) (string, error) {
// Sync doc
// Run test
return "", nil
}
+13
View File
@@ -0,0 +1,13 @@
package query
import (
"context"
)
func (s *Service) Test(ctx context.Context, filters Test) (string, error) {
// TODO
// Sync doc
// Run test
return "", nil
}
+45
View File
@@ -0,0 +1,45 @@
package query
import (
"context"
"fmt"
contextfull "queryorchestration/internal/contextFull"
"queryorchestration/internal/database"
jsonextractor "queryorchestration/internal/jsonExtractor"
queryprocessor "queryorchestration/internal/queryProcessor"
)
func (s *Service) Update(ctx context.Context, entity *queryprocessor.Update) error {
dbType, err := s.db.GetQueryType(ctx, database.MustToDBUUID(entity.ID))
if err != nil {
return err
}
qType, err := queryprocessor.ParseDBType(dbType)
if err != nil {
return err
}
validator, err := s.getUpdator(qType)
if err != nil {
return err
}
err = validator.Update(ctx, entity)
if err != nil {
return err
}
return nil
}
func (s *Service) getUpdator(qType queryprocessor.Type) (queryprocessor.Updator, error) {
switch qType {
case queryprocessor.TypeJsonExtractor:
return jsonextractor.NewUpdator(s.db), nil
case queryprocessor.TypeContextFull:
return contextfull.NewUpdator(s.db), nil
default:
return nil, fmt.Errorf("attempting to process invalid query type")
}
}
@@ -1,25 +1,13 @@
package query
package queryprocessor
import (
"fmt"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"github.com/google/uuid"
)
func ParseDBQueryRow(dbQuery *repository.GetCollectorQueriesRow) (*QueryRow, error) {
t, err := ParseDBNullType(dbQuery.Type)
if err != nil {
return nil, err
}
return &QueryRow{
ID: database.MustToUUID(dbQuery.Queryid),
Type: t,
RequiredQueryID: database.MustToUUID(dbQuery.Requiredqueryid),
Version: dbQuery.Queryversion.Int32,
}, nil
}
func ParseDBNullType(qType repository.NullQuerytype) (Type, error) {
if !qType.Valid {
return TypeJsonExtractor, fmt.Errorf("invalid database query type")
@@ -53,3 +41,22 @@ func ToDBQueryType(t Type) (repository.NullQuerytype, error) {
return repository.NullQuerytype{Querytype: dbType, Valid: true}, nil
}
func ParseDBQuery(q *repository.GetCollectorQueriesRow) (*Query, error) {
reqQueryIDs := make([]uuid.UUID, len(q.Requiredids))
for index, id := range q.Requiredids {
reqQueryIDs[index] = database.MustToUUID(id)
}
qType, err := ParseDBNullType(q.Type)
if err != nil {
return nil, err
}
return &Query{
ID: database.MustToUUID(q.Queryid),
Version: q.Queryversion.Int32,
Type: qType,
RequiredQueryIDs: reqQueryIDs,
}, nil
}
+49
View File
@@ -0,0 +1,49 @@
package queryprocessor
import (
"context"
"queryorchestration/internal/result"
"github.com/google/uuid"
)
type Type int
const (
TypeJsonExtractor = iota
TypeContextFull
)
type Create struct {
Type Type
RequiredQueryIDs []uuid.UUID
Config interface{}
}
type Update struct {
ID uuid.UUID
RequiredQueryIDs []uuid.UUID
Config interface{}
}
type Query struct {
ID uuid.UUID
Type Type
Version int32
RequiredQueryIDs []uuid.UUID
Config interface{}
}
type Creator interface {
Validate(ctx context.Context, entity *Create) error
Create(ctx context.Context, entity *Create) (uuid.UUID, error)
}
type Updator interface {
Validate(ctx context.Context, entity *Update) error
Update(ctx context.Context, entity *Update) error
}
type Processor interface {
Process(ctx context.Context, query Query, values *[]result.Value) (string, error)
}
+18 -12
View File
@@ -3,7 +3,7 @@ package queryQueue
import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
)
func (q *Queue) getUnsyncedQueries() {
@@ -36,9 +36,9 @@ func (c *Queue) getCollectorQueries(ctx context.Context) error {
return err
}
cleanQueries := make([]query.QueryRow, len(queries))
cleanQueries := make([]queryprocessor.Query, len(queries))
for index, dbQuery := range queries {
cleanQuery, err := query.ParseDBQueryRow(&dbQuery)
cleanQuery, err := queryprocessor.ParseDBQuery(&dbQuery)
if err != nil {
return err
}
@@ -51,33 +51,39 @@ func (c *Queue) getCollectorQueries(ctx context.Context) error {
return nil
}
func (q *Queue) Add(qu *query.QueryRow) {
dependentQueries := []query.QueryRow{}
func (q *Queue) Add(qu *queryprocessor.Query) {
dependentQueries := []queryprocessor.Query{}
requiredIndex := -1
if q.unsyncedQueue == nil {
q.unsyncedQueue = &[]query.QueryRow{}
q.unsyncedQueue = &[]queryprocessor.Query{}
} else {
for index, entry := range *q.unsyncedQueue {
if entry.ID == qu.ID {
return
}
if entry.ID == qu.RequiredQueryID {
requiredIndex = index
for _, id := range qu.RequiredQueryIDs {
if entry.ID == id {
requiredIndex = index
break
}
}
}
}
for _, entry := range *q.collectorQueries {
if entry.RequiredQueryID == qu.ID {
dependentQueries = append(dependentQueries, entry)
for _, id := range entry.RequiredQueryIDs {
if qu.ID == id {
dependentQueries = append(dependentQueries, entry)
break
}
}
}
if requiredIndex != -1 {
*q.unsyncedQueue = append((*q.unsyncedQueue)[:requiredIndex+1], append([]query.QueryRow{*qu}, (*q.unsyncedQueue)[requiredIndex+1:]...)...)
*q.unsyncedQueue = append((*q.unsyncedQueue)[:requiredIndex+1], append([]queryprocessor.Query{*qu}, (*q.unsyncedQueue)[requiredIndex+1:]...)...)
} else {
*q.unsyncedQueue = append([]query.QueryRow{*qu}, *q.unsyncedQueue...)
*q.unsyncedQueue = append([]queryprocessor.Query{*qu}, *q.unsyncedQueue...)
}
for _, entry := range dependentQueries {
+7 -15
View File
@@ -7,10 +7,9 @@ import (
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
jsonextractor "queryorchestration/internal/jsonExtractor"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
"queryorchestration/internal/result"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
)
@@ -31,16 +30,9 @@ func (q *Queue) Execute(ctx context.Context) error {
return nil
}
func (q *Queue) executeQuery(ctx context.Context, qu query.QueryRow) error {
requiredQueryIDs := []uuid.UUID{}
for _, entry := range *q.collectorQueries {
if entry.ID == qu.ID && entry.RequiredQueryID != uuid.Nil {
requiredQueryIDs = append(requiredQueryIDs, entry.RequiredQueryID)
}
}
resultIDs := make([]pgtype.UUID, len(requiredQueryIDs))
for index, id := range requiredQueryIDs {
func (q *Queue) executeQuery(ctx context.Context, qu queryprocessor.Query) error {
resultIDs := make([]pgtype.UUID, len(qu.RequiredQueryIDs))
for index, id := range qu.RequiredQueryIDs {
var queryVersion int32
for _, entry := range *q.collectorQueries {
if entry.ID == id {
@@ -81,7 +73,7 @@ func (q *Queue) executeQuery(ctx context.Context, qu query.QueryRow) error {
}
func (q *Queue) getResultValue(res *repository.ListResultValuesByIDRow) (result.Value, error) {
var queryType query.Type
var queryType queryprocessor.Type
for _, qu := range *q.collectorQueries {
if qu.ID == database.MustToUUID(res.Queryid) {
queryType = qu.Type
@@ -89,9 +81,9 @@ func (q *Queue) getResultValue(res *repository.ListResultValuesByIDRow) (result.
}
switch queryType {
case query.TypeJsonExtractor:
case queryprocessor.TypeJsonExtractor:
return jsonextractor.NewResult(res.Value), nil
case query.TypeContextFull:
case queryprocessor.TypeContextFull:
return contextfull.NewResult(res.Value), nil
default:
return nil, fmt.Errorf("attempting to process invalid query type")
+7 -7
View File
@@ -5,11 +5,11 @@ import (
"fmt"
contextfull "queryorchestration/internal/contextFull"
jsonextractor "queryorchestration/internal/jsonExtractor"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
"queryorchestration/internal/result"
)
func (q *Queue) setResult(ctx context.Context, qu query.QueryRow, resultValues *[]result.Value) error {
func (q *Queue) setResult(ctx context.Context, qu queryprocessor.Query, resultValues *[]result.Value) error {
processor, err := q.getProcessor(qu.Type)
if err != nil {
return err
@@ -41,12 +41,12 @@ func (q *Queue) setResult(ctx context.Context, qu query.QueryRow, resultValues *
return nil
}
func (q *Queue) getProcessor(queryType query.Type) (query.Processor, error) {
func (q *Queue) getProcessor(queryType queryprocessor.Type) (queryprocessor.Processor, error) {
switch queryType {
case query.TypeJsonExtractor:
return jsonextractor.New(q.db), nil
case query.TypeContextFull:
return contextfull.New(), nil
case queryprocessor.TypeJsonExtractor:
return jsonextractor.NewExtractor(q.db), nil
case queryprocessor.TypeContextFull:
return contextfull.NewExtractor(), nil
default:
return nil, fmt.Errorf("attempting to process invalid query type")
}
+4 -4
View File
@@ -4,15 +4,15 @@ import (
"context"
"queryorchestration/internal/collector"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
"queryorchestration/internal/result"
"github.com/google/uuid"
)
type Queue struct {
unsyncedQueue *[]query.QueryRow
collectorQueries *[]query.QueryRow
unsyncedQueue *[]queryprocessor.Query
collectorQueries *[]queryprocessor.Query
results *[]result.Result
collector *collector.Collector
db *repository.Queries
@@ -41,6 +41,6 @@ func New(ctx context.Context, db *repository.Queries, coll *collector.Collector,
return &queue, nil
}
func (q *Queue) GetQueue() []query.QueryRow {
func (q *Queue) GetQueue() []queryprocessor.Query {
return *q.unsyncedQueue
}
-2
View File
@@ -15,6 +15,4 @@ tasks:
- protolint lint -fix {{.PROTO_DIR}}
generate:
cmds:
- pwd
- mkdir -p {{.API_DIR}}/serviceInterfaces
- protoc --proto_path={{.PROTO_DIR}} --go_out={{.API_DIR}}/serviceInterfaces --go-grpc_out={{.API_DIR}} --go_opt=paths=source_relative --experimental_allow_proto3_optional main.proto
@@ -3,7 +3,7 @@ package document_test
import (
"context"
contextfull "queryorchestration/internal/contextFull"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
"queryorchestration/internal/result"
"testing"
@@ -14,13 +14,13 @@ import (
func TestContextFull(t *testing.T) {
ctx := context.Background()
extractor := contextfull.New()
extractor := contextfull.NewExtractor()
query := query.QueryRow{
ID: uuid.New(),
Type: query.TypeJsonExtractor,
RequiredQueryID: uuid.Nil,
Version: int32(1),
query := queryprocessor.Query{
ID: uuid.New(),
Type: queryprocessor.TypeJsonExtractor,
RequiredQueryIDs: []uuid.UUID{},
Version: int32(1),
}
values := &[]result.Value{}
+6 -6
View File
@@ -48,8 +48,8 @@ func TestSyncIsSynced(t *testing.T) {
)
db.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorId).
WillReturnRows(
pgxmock.NewRows([]string{"collectorId", "queryId", "type", "requiredQueryId", "queryVersion"}).
AddRow(dbCollectorId, pgtype.UUID{}, repository.NullQuerytype{Querytype: repository.QuerytypeJsonExtractor, Valid: true}, pgtype.UUID{}, pgtype.Int4{Int32: int32(1), Valid: true}),
pgxmock.NewRows([]string{"collectorId", "queryId", "type", "queryVersion", "requiredIds"}).
AddRow(dbCollectorId, pgtype.UUID{}, repository.NullQuerytype{Querytype: repository.QuerytypeJsonExtractor, Valid: true}, pgtype.Int4{Int32: int32(1), Valid: true}, []pgtype.UUID{}),
)
docSvc := document.New(queries)
@@ -131,8 +131,8 @@ func TestSyncDBFail(t *testing.T) {
errr = "database failure"
db.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorId).
WillReturnRows(
pgxmock.NewRows([]string{"collectorId", "queryId", "type", "requiredQueryId", "queryVersion"}).
AddRow(dbCollectorId, dbQueryID, repository.NullQuerytype{Querytype: repository.QuerytypeJsonExtractor, Valid: true}, pgtype.UUID{}, pgtype.Int4{Int32: int32(1), Valid: true}),
pgxmock.NewRows([]string{"collectorId", "queryId", "type", "queryVersion", "requiredIds"}).
AddRow(dbCollectorId, dbQueryID, repository.NullQuerytype{Querytype: repository.QuerytypeJsonExtractor, Valid: true}, pgtype.Int4{Int32: int32(1), Valid: true}, []pgtype.UUID{}),
)
db.ExpectQuery("name: ListResultValuesByID :many").WithArgs([]pgtype.UUID{}).
WillReturnError(errors.New(errr))
@@ -176,8 +176,8 @@ func TestSync(t *testing.T) {
)
db.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorId).
WillReturnRows(
pgxmock.NewRows([]string{"collectorId", "queryId", "type", "requiredQueryId", "queryVersion"}).
AddRow(dbCollectorId, dbQueryID, repository.NullQuerytype{Querytype: repository.QuerytypeJsonExtractor, Valid: true}, pgtype.UUID{}, pgtype.Int4{Int32: int32(1), Valid: true}),
pgxmock.NewRows([]string{"collectorId", "queryId", "type", "queryVersion", "requiredIds"}).
AddRow(dbCollectorId, dbQueryID, repository.NullQuerytype{Querytype: repository.QuerytypeJsonExtractor, Valid: true}, pgtype.Int4{Int32: int32(1), Valid: true}, []pgtype.UUID{}),
)
db.ExpectQuery("name: ListResultValuesByID :many").WithArgs([]pgtype.UUID{}).
WillReturnRows(
@@ -7,7 +7,7 @@ import (
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
jsonextractor "queryorchestration/internal/jsonExtractor"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
"queryorchestration/internal/result"
"testing"
@@ -28,13 +28,13 @@ func TestJSONProcess(t *testing.T) {
queries := repository.New(db)
extractor := jsonextractor.New(queries)
extractor := jsonextractor.NewExtractor(queries)
query := query.QueryRow{
ID: uuid.New(),
Type: query.TypeJsonExtractor,
RequiredQueryID: uuid.Nil,
Version: int32(1),
query := queryprocessor.Query{
ID: uuid.New(),
Type: queryprocessor.TypeJsonExtractor,
RequiredQueryIDs: []uuid.UUID{},
Version: int32(1),
}
entryValue := "value"
@@ -97,13 +97,13 @@ func TestJSONProcessJSON(t *testing.T) {
queries := repository.New(db)
extractor := jsonextractor.New(queries)
extractor := jsonextractor.NewExtractor(queries)
query := query.QueryRow{
ID: uuid.New(),
Type: query.TypeJsonExtractor,
RequiredQueryID: uuid.Nil,
Version: int32(1),
query := queryprocessor.Query{
ID: uuid.New(),
Type: queryprocessor.TypeJsonExtractor,
RequiredQueryIDs: []uuid.UUID{},
Version: int32(1),
}
entryValue := "value"
@@ -183,13 +183,13 @@ func TestJSONProcessResults(t *testing.T) {
queries := repository.New(db)
extractor := jsonextractor.New(queries)
extractor := jsonextractor.NewExtractor(queries)
query := query.QueryRow{
ID: uuid.New(),
Type: query.TypeJsonExtractor,
RequiredQueryID: uuid.Nil,
Version: int32(1),
query := queryprocessor.Query{
ID: uuid.New(),
Type: queryprocessor.TypeJsonExtractor,
RequiredQueryIDs: []uuid.UUID{},
Version: int32(1),
}
results := &[]result.Value{}
+2 -1
View File
@@ -5,6 +5,7 @@ import (
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
"testing"
"github.com/google/uuid"
@@ -28,7 +29,7 @@ func TestGet(t *testing.T) {
config := "{\"path\":\"example_path\"}"
query := query.Query{
ID: uuid.New(),
Type: query.TypeJsonExtractor,
Type: queryprocessor.TypeJsonExtractor,
Version: int32(1),
RequiredQueryIDs: []uuid.UUID{
uuid.New(),
+24 -24
View File
@@ -2,7 +2,7 @@ package document_test
import (
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
"testing"
"github.com/google/uuid"
@@ -12,63 +12,63 @@ import (
func TestParseDBQueryRow(t *testing.T) {
dbResult := repository.GetCollectorQueriesRow{
Collectorid: pgtype.UUID{},
Queryid: pgtype.UUID{},
Requiredqueryid: pgtype.UUID{},
Type: repository.NullQuerytype{Valid: true, Querytype: repository.QuerytypeJsonExtractor},
Queryversion: pgtype.Int4{},
Collectorid: pgtype.UUID{},
Queryid: pgtype.UUID{},
Requiredids: []pgtype.UUID{},
Type: repository.NullQuerytype{Valid: true, Querytype: repository.QuerytypeJsonExtractor},
Queryversion: pgtype.Int4{},
}
value, err := query.ParseDBQueryRow(&dbResult)
value, err := queryprocessor.ParseDBQuery(&dbResult)
assert.Nil(t, err)
assert.Equal(t, uuid.Nil, value.ID)
assert.Equal(t, uuid.Nil, value.RequiredQueryID)
assert.Equal(t, []uuid.UUID{}, value.RequiredQueryIDs)
assert.Equal(t, int32(0), value.Version)
assert.Equal(t, query.Type(query.TypeJsonExtractor), value.Type)
assert.Equal(t, queryprocessor.Type(queryprocessor.TypeJsonExtractor), value.Type)
dbResult.Type = repository.NullQuerytype{}
_, err = query.ParseDBQueryRow(&dbResult)
_, err = queryprocessor.ParseDBQuery(&dbResult)
assert.EqualError(t, err, "invalid database query type")
}
func TestParseDBNullType(t *testing.T) {
qType := repository.NullQuerytype{Valid: true, Querytype: repository.QuerytypeJsonExtractor}
value, err := query.ParseDBNullType(qType)
value, err := queryprocessor.ParseDBNullType(qType)
assert.Nil(t, err)
assert.Equal(t, query.Type(query.TypeJsonExtractor), value)
assert.Equal(t, queryprocessor.Type(queryprocessor.TypeJsonExtractor), value)
qType = repository.NullQuerytype{}
_, err = query.ParseDBNullType(qType)
_, err = queryprocessor.ParseDBNullType(qType)
assert.EqualError(t, err, "invalid database query type")
qType = repository.NullQuerytype{Valid: true}
_, err = query.ParseDBNullType(qType)
_, err = queryprocessor.ParseDBNullType(qType)
assert.EqualError(t, err, "invalid database query type")
}
func TestParseDBType(t *testing.T) {
qType := repository.QuerytypeJsonExtractor
value, err := query.ParseDBType(qType)
value, err := queryprocessor.ParseDBType(qType)
assert.Nil(t, err)
assert.Equal(t, query.Type(query.TypeJsonExtractor), value)
assert.Equal(t, queryprocessor.Type(queryprocessor.TypeJsonExtractor), value)
qType = repository.QuerytypeContextFull
value, err = query.ParseDBType(qType)
value, err = queryprocessor.ParseDBType(qType)
assert.Nil(t, err)
assert.Equal(t, query.Type(query.TypeContextFull), value)
assert.Equal(t, queryprocessor.Type(queryprocessor.TypeContextFull), value)
}
func TestToDBQueryType(t *testing.T) {
dbQueryType := query.Type(query.TypeJsonExtractor)
value, err := query.ToDBQueryType(dbQueryType)
dbQueryType := queryprocessor.Type(queryprocessor.TypeJsonExtractor)
value, err := queryprocessor.ToDBQueryType(dbQueryType)
assert.Nil(t, err)
assert.Equal(t, repository.NullQuerytype{Querytype: repository.QuerytypeJsonExtractor, Valid: true}, value)
dbQueryType = query.Type(-1)
_, err = query.ToDBQueryType(dbQueryType)
dbQueryType = queryprocessor.Type(-1)
_, err = queryprocessor.ToDBQueryType(dbQueryType)
assert.EqualError(t, err, "invalid database query type")
dbQueryType = query.Type(query.TypeContextFull)
value, err = query.ToDBQueryType(dbQueryType)
dbQueryType = queryprocessor.Type(queryprocessor.TypeContextFull)
value, err = queryprocessor.ToDBQueryType(dbQueryType)
assert.Nil(t, err)
assert.Equal(t, repository.NullQuerytype{Querytype: repository.QuerytypeContextFull, Valid: true}, value)
}
+22 -19
View File
@@ -7,7 +7,7 @@ import (
"queryorchestration/internal/collector"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
"queryorchestration/internal/queryQueue"
"queryorchestration/internal/result"
"testing"
@@ -56,24 +56,27 @@ func TestQueue(t *testing.T) {
querySixVersion := int32(6)
contextID := uuid.New()
contextVersion := int32(1)
collectorQueries := []query.QueryRow{
{ID: contextID, Type: query.TypeContextFull, RequiredQueryID: uuid.Nil, Version: contextVersion},
{ID: queryOneID, Type: query.TypeJsonExtractor, RequiredQueryID: contextID, Version: queryOneVersion},
{ID: queryTwoID, Type: query.TypeJsonExtractor, RequiredQueryID: queryOneID, Version: queryTwoVersion},
{ID: queryThreeID, Type: query.TypeJsonExtractor, RequiredQueryID: queryOneID, Version: queryThreeVersion},
{ID: queryFourID, Type: query.TypeJsonExtractor, RequiredQueryID: contextID, Version: queryFourVersion},
{ID: queryFiveID, Type: query.TypeJsonExtractor, RequiredQueryID: querySixID, Version: queryFiveVersion},
{ID: querySixID, Type: query.TypeJsonExtractor, RequiredQueryID: contextID, Version: querySixVersion},
collectorQueries := []queryprocessor.Query{
{ID: contextID, Type: queryprocessor.TypeContextFull, RequiredQueryIDs: []uuid.UUID{}, Version: contextVersion},
{ID: queryOneID, Type: queryprocessor.TypeJsonExtractor, RequiredQueryIDs: []uuid.UUID{contextID}, Version: queryOneVersion},
{ID: queryTwoID, Type: queryprocessor.TypeJsonExtractor, RequiredQueryIDs: []uuid.UUID{queryOneID}, Version: queryTwoVersion},
{ID: queryThreeID, Type: queryprocessor.TypeJsonExtractor, RequiredQueryIDs: []uuid.UUID{queryOneID}, Version: queryThreeVersion},
{ID: queryFourID, Type: queryprocessor.TypeJsonExtractor, RequiredQueryIDs: []uuid.UUID{contextID}, Version: queryFourVersion},
{ID: queryFiveID, Type: queryprocessor.TypeJsonExtractor, RequiredQueryIDs: []uuid.UUID{querySixID}, Version: queryFiveVersion},
{ID: querySixID, Type: queryprocessor.TypeJsonExtractor, RequiredQueryIDs: []uuid.UUID{contextID}, Version: querySixVersion},
}
rows := pgxmock.NewRows([]string{"collectorId", "queryId", "type", "requiredQueryId", "queryVersion"})
rows := pgxmock.NewRows([]string{"collectorId", "queryId", "type", "queryVersion", "requiredIds"})
for _, q := range collectorQueries {
dbID := database.MustToDBUUID(q.ID)
dbReqID := database.MustToDBUUID(q.RequiredQueryID)
ty, err := query.ToDBQueryType(q.Type)
dbReqIDs := make([]pgtype.UUID, len(q.RequiredQueryIDs))
for index, id := range q.RequiredQueryIDs {
dbReqIDs[index] = database.MustToDBUUID(id)
}
ty, err := queryprocessor.ToDBQueryType(q.Type)
assert.Nil(t, err)
rows = rows.
AddRow(dbCollectorID, dbID, ty, dbReqID, pgtype.Int4{Int32: int32(q.Version), Valid: true})
AddRow(dbCollectorID, dbID, ty, pgtype.Int4{Int32: int32(q.Version), Valid: true}, dbReqIDs)
}
db.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorID).WillReturnRows(rows)
@@ -86,12 +89,12 @@ func TestQueue(t *testing.T) {
{ID: uuid.New(), QueryID: queryOneID, QueryVersion: queryOneVersion - 1},
}
expectedQueries := []query.QueryRow{
{ID: querySixID, Type: query.TypeJsonExtractor, RequiredQueryID: contextID, Version: querySixVersion},
{ID: queryFiveID, Type: query.TypeJsonExtractor, RequiredQueryID: querySixID, Version: queryFiveVersion},
{ID: queryOneID, Type: query.TypeJsonExtractor, RequiredQueryID: contextID, Version: queryOneVersion},
{ID: queryThreeID, Type: query.TypeJsonExtractor, RequiredQueryID: queryOneID, Version: queryThreeVersion},
{ID: queryTwoID, Type: query.TypeJsonExtractor, RequiredQueryID: queryOneID, Version: queryTwoVersion},
expectedQueries := []queryprocessor.Query{
{ID: querySixID, Type: queryprocessor.TypeJsonExtractor, RequiredQueryIDs: []uuid.UUID{contextID}, Version: querySixVersion},
{ID: queryFiveID, Type: queryprocessor.TypeJsonExtractor, RequiredQueryIDs: []uuid.UUID{querySixID}, Version: queryFiveVersion},
{ID: queryOneID, Type: queryprocessor.TypeJsonExtractor, RequiredQueryIDs: []uuid.UUID{contextID}, Version: queryOneVersion},
{ID: queryThreeID, Type: queryprocessor.TypeJsonExtractor, RequiredQueryIDs: []uuid.UUID{queryOneID}, Version: queryThreeVersion},
{ID: queryTwoID, Type: queryprocessor.TypeJsonExtractor, RequiredQueryIDs: []uuid.UUID{queryOneID}, Version: queryTwoVersion},
}
docID := uuid.New()