Merged in feature/shorttestsanddirtidy (pull request #26)

Add short tests and Tidy internal directories

* complete the tasks
This commit is contained in:
Michael McGuinness
2025-01-17 12:00:32 +00:00
parent b453f6cb23
commit fa95d733ca
84 changed files with 171 additions and 101 deletions
+3 -3
View File
@@ -3,11 +3,11 @@ package query
import (
"context"
"fmt"
contextfull "queryorchestration/internal/contextFull"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
jsonextractor "queryorchestration/internal/jsonExtractor"
queryprocessor "queryorchestration/internal/queryProcessor"
queryprocessor "queryorchestration/internal/query/processor"
contextfull "queryorchestration/internal/query/types/contextFull"
jsonextractor "queryorchestration/internal/query/types/jsonExtractor"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
queryprocessor "queryorchestration/internal/query/processor"
"testing"
"github.com/google/uuid"
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/queryProcessor"
queryprocessor "queryorchestration/internal/query/processor"
"testing"
"github.com/google/uuid"
+74
View File
@@ -0,0 +1,74 @@
package document
import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/job/collector"
queryqueue "queryorchestration/internal/query/queue"
"queryorchestration/internal/query/result"
"github.com/google/uuid"
)
type Document struct {
ID uuid.UUID `json:"id" validate:"required,uuid"`
JobID uuid.UUID `json:"jobId" validate:"required,uuid"`
Name string `json:"name" validate:"required"`
CleanVersion int32 `json:"cleanVersion" validate:"required,gt=0"`
TextVersion int32 `json:"textVersion" validate:"required,gt=0"`
}
type Service struct {
db *database.Connection
}
func New(db *database.Connection) *Service {
return &Service{
db,
}
}
func (s *Service) Sync(ctx context.Context, doc *Document) error {
collector, err := collector.NewByJobId(ctx, s.db, doc.JobID)
if err != nil {
return err
}
results, err := s.getResults(ctx, doc.ID, collector)
if err != nil {
return err
}
queue, err := queryqueue.New(ctx, s.db, collector, results, doc.ID, doc.CleanVersion, doc.TextVersion)
if err != nil {
return err
}
err = queue.Execute(ctx)
if err != nil {
return err
}
return nil
}
func (s *Service) getResults(ctx context.Context, id uuid.UUID, coll *collector.Collector) ([]*result.Result, error) {
docID := database.MustToDBUUID(id)
results, err := s.db.Queries.ListResultsByDocumentID(ctx, &repository.ListResultsByDocumentIDParams{
Documentid: docID,
Textversion: coll.MinTextVersion,
Cleanversion: coll.MinCleanVersion,
})
if err != nil {
return nil, err
}
cleanResults := make([]*result.Result, len(results))
for index, dbResult := range results {
cleanResults[index] = result.Parse(dbResult)
}
return cleanResults, nil
}
+199
View File
@@ -0,0 +1,199 @@
package document_test
import (
"context"
"errors"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query/document"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestSyncIsSynced(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
doc := document.Document{
ID: uuid.New(),
JobID: uuid.New(),
Name: "document_name",
}
dbCollectorId := database.MustToDBUUID(uuid.New())
dbJobID := database.MustToDBUUID(doc.JobID)
minCleanVersion := int32(1)
minTextVersion := int32(1)
qV := int32(1)
pool.ExpectQuery("name: GetCollectorFromJobID :one").WithArgs(dbJobID).
WillReturnRows(
pgxmock.NewRows([]string{"id", "jobId", "minCleanVersion", "minTextVersion"}).
AddRow(dbCollectorId, dbJobID, minCleanVersion, minTextVersion),
)
pool.ExpectQuery("name: ListResultsByDocumentID :many").WithArgs(database.MustToDBUUID(doc.ID), minCleanVersion, minTextVersion).
WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "queryVersion"}).
AddRow(pgtype.UUID{}, pgtype.UUID{}, qV),
)
pool.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorId).
WillReturnRows(
pgxmock.NewRows([]string{"collectorId", "queryId", "type", "queryVersion", "requiredIds"}).
AddRow(dbCollectorId, pgtype.UUID{}, repository.NullQuerytype{Querytype: repository.QuerytypeJsonExtractor, Valid: true}, &qV, []pgtype.UUID{}),
)
docSvc := document.New(db)
err = docSvc.Sync(ctx, &doc)
assert.Nil(t, err)
}
func TestSyncDBFail(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
doc := document.Document{
ID: uuid.New(),
JobID: uuid.New(),
Name: "document_name",
}
dbCollectorId := database.MustToDBUUID(uuid.New())
dbJobID := database.MustToDBUUID(doc.JobID)
dbQueryID := database.MustToDBUUID(uuid.New())
minCleanVersion := int32(1)
minTextVersion := int32(1)
pool.ExpectQuery("name: GetCollectorFromJobID :one").WithArgs(dbJobID).
WillReturnRows(
pgxmock.NewRows([]string{"id", "jobId", "minCleanVersion", "minTextVersion"}),
)
docSvc := document.New(db)
err = docSvc.Sync(ctx, &doc)
assert.EqualError(t, err, "no rows in result set")
pool.ExpectQuery("name: GetCollectorFromJobID :one").WithArgs(dbJobID).
WillReturnRows(
pgxmock.NewRows([]string{"id", "jobId", "minCleanVersion", "minTextVersion"}).
AddRow(dbCollectorId, dbJobID, minCleanVersion, minTextVersion),
)
dbErr := "database failure"
pool.ExpectQuery("name: ListResultsByDocumentID :many").WithArgs(database.MustToDBUUID(doc.ID), minCleanVersion, minTextVersion).
WillReturnError(errors.New(dbErr))
docSvc = document.New(db)
err = docSvc.Sync(ctx, &doc)
assert.EqualError(t, err, dbErr)
pool.ExpectQuery("name: GetCollectorFromJobID :one").WithArgs(dbJobID).
WillReturnRows(
pgxmock.NewRows([]string{"id", "jobId", "minCleanVersion", "minTextVersion"}).
AddRow(dbCollectorId, dbJobID, minCleanVersion, minTextVersion),
)
pool.ExpectQuery("name: ListResultsByDocumentID :many").WithArgs(database.MustToDBUUID(doc.ID), minCleanVersion, minTextVersion).
WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "queryVersion"}),
)
dbErr = "database failure"
pool.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorId).
WillReturnError(errors.New(dbErr))
docSvc = document.New(db)
err = docSvc.Sync(ctx, &doc)
assert.EqualError(t, err, dbErr)
pool.ExpectQuery("name: GetCollectorFromJobID :one").WithArgs(dbJobID).
WillReturnRows(
pgxmock.NewRows([]string{"id", "jobId", "minCleanVersion", "minTextVersion"}).
AddRow(dbCollectorId, dbJobID, minCleanVersion, minTextVersion),
)
pool.ExpectQuery("name: ListResultsByDocumentID :many").WithArgs(database.MustToDBUUID(doc.ID), minCleanVersion, minTextVersion).
WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "queryVersion"}),
)
dbErr = "database failure"
qV := int32(1)
pool.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorId).
WillReturnRows(
pgxmock.NewRows([]string{"collectorId", "queryId", "type", "queryVersion", "requiredIds"}).
AddRow(dbCollectorId, dbQueryID, repository.NullQuerytype{Querytype: repository.QuerytypeJsonExtractor, Valid: true}, &qV, []pgtype.UUID{}),
)
pool.ExpectQuery("name: ListResultValuesByID :many").WithArgs([]pgtype.UUID{}).
WillReturnError(errors.New(dbErr))
docSvc = document.New(db)
err = docSvc.Sync(ctx, &doc)
assert.EqualError(t, err, dbErr)
}
func TestSync(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
doc := document.Document{
ID: uuid.New(),
JobID: uuid.New(),
Name: "document_name",
}
dbCollectorId := database.MustToDBUUID(uuid.New())
dbJobID := database.MustToDBUUID(doc.JobID)
dbQueryID := database.MustToDBUUID(uuid.New())
minCleanVersion := int32(1)
minTextVersion := int32(1)
pool.ExpectQuery("name: GetCollectorFromJobID :one").WithArgs(dbJobID).
WillReturnRows(
pgxmock.NewRows([]string{"id", "jobId", "minCleanVersion", "minTextVersion"}).
AddRow(dbCollectorId, dbJobID, minCleanVersion, minTextVersion),
)
pool.ExpectQuery("name: ListResultsByDocumentID :many").WithArgs(database.MustToDBUUID(doc.ID), minCleanVersion, minTextVersion).
WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "queryVersion"}),
)
qV := int32(1)
pool.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorId).
WillReturnRows(
pgxmock.NewRows([]string{"collectorId", "queryId", "type", "queryVersion", "requiredIds"}).
AddRow(dbCollectorId, dbQueryID, repository.NullQuerytype{Querytype: repository.QuerytypeJsonExtractor, Valid: true}, &qV, []pgtype.UUID{}),
)
pool.ExpectQuery("name: ListResultValuesByID :many").WithArgs([]pgtype.UUID{}).
WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "value"}),
)
docSvc := document.New(db)
err = docSvc.Sync(ctx, &doc)
assert.EqualError(t, err, "JSON Extraction requires 1 result")
}
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/queryProcessor"
queryprocessor "queryorchestration/internal/query/processor"
"github.com/google/uuid"
)
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
queryprocessor "queryorchestration/internal/query/processor"
"testing"
"github.com/google/uuid"
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
queryprocessor "queryorchestration/internal/query/processor"
"testing"
"github.com/google/uuid"
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
queryprocessor "queryorchestration/internal/query/processor"
"testing"
"github.com/google/uuid"
+80
View File
@@ -0,0 +1,80 @@
package queryprocessor
import (
"fmt"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
)
func ParseDBNullType(qType repository.NullQuerytype) (Type, error) {
if !qType.Valid {
return TypeJsonExtractor, fmt.Errorf("invalid database query type")
}
return ParseDBType(qType.Querytype)
}
func ParseDBType(qType repository.Querytype) (Type, error) {
switch qType {
case repository.QuerytypeJsonExtractor:
return TypeJsonExtractor, nil
case repository.QuerytypeContextFull:
return TypeContextFull, nil
default:
return TypeJsonExtractor, fmt.Errorf("invalid database query type")
}
}
func ToDBQueryType(t Type) (repository.Querytype, error) {
var dbType repository.Querytype
switch t {
case TypeJsonExtractor:
dbType = repository.QuerytypeJsonExtractor
case TypeContextFull:
dbType = repository.QuerytypeContextFull
default:
return repository.QuerytypeContextFull, fmt.Errorf("invalid database query type")
}
return dbType, nil
}
func ToDBQueryTypeArray(t []Type) ([]repository.Querytype, error) {
arr := make([]repository.Querytype, len(t))
for index, value := range t {
v, err := ToDBQueryType(value)
if err != nil {
return nil, err
}
arr[index] = v
}
return arr, nil
}
func ToDBNullQueryType(t Type) (repository.NullQuerytype, error) {
dbType, err := ToDBQueryType(t)
if err != nil {
return repository.NullQuerytype{}, err
}
return repository.NullQuerytype{Querytype: dbType, Valid: true}, nil
}
func ParseDBCollectorQuery(q *repository.GetCollectorQueriesRow) (*Query, error) {
reqQueryIDs := database.MustToUUIDArray(q.Requiredids)
qType, err := ParseDBNullType(q.Type)
if err != nil {
return nil, err
}
return &Query{
ID: database.MustToUUID(q.Queryid),
Version: *q.Queryversion,
Type: qType,
RequiredQueryIDs: reqQueryIDs,
}, nil
}
+110
View File
@@ -0,0 +1,110 @@
package queryprocessor_test
import (
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/query/processor"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
"github.com/stretchr/testify/assert"
)
func TestParseDBCollectorQuery(t *testing.T) {
qV := int32(0)
dbResult := repository.GetCollectorQueriesRow{
Collectorid: pgtype.UUID{},
Queryid: pgtype.UUID{},
Requiredids: []pgtype.UUID{},
Type: repository.NullQuerytype{Valid: true, Querytype: repository.QuerytypeJsonExtractor},
Queryversion: &qV,
}
value, err := queryprocessor.ParseDBCollectorQuery(&dbResult)
assert.Nil(t, err)
assert.Equal(t, uuid.Nil, value.ID)
assert.Equal(t, []uuid.UUID{}, value.RequiredQueryIDs)
assert.Equal(t, int32(0), value.Version)
assert.Equal(t, queryprocessor.Type(queryprocessor.TypeJsonExtractor), value.Type)
dbResult.Type = repository.NullQuerytype{}
_, err = queryprocessor.ParseDBCollectorQuery(&dbResult)
assert.EqualError(t, err, "invalid database query type")
}
func TestParseDBNullType(t *testing.T) {
qType := repository.NullQuerytype{Valid: true, Querytype: repository.QuerytypeJsonExtractor}
value, err := queryprocessor.ParseDBNullType(qType)
assert.Nil(t, err)
assert.Equal(t, queryprocessor.Type(queryprocessor.TypeJsonExtractor), value)
qType = repository.NullQuerytype{}
_, err = queryprocessor.ParseDBNullType(qType)
assert.EqualError(t, err, "invalid database query type")
qType = repository.NullQuerytype{Valid: true}
_, err = queryprocessor.ParseDBNullType(qType)
assert.EqualError(t, err, "invalid database query type")
}
func TestParseDBType(t *testing.T) {
qType := repository.QuerytypeJsonExtractor
value, err := queryprocessor.ParseDBType(qType)
assert.Nil(t, err)
assert.Equal(t, queryprocessor.Type(queryprocessor.TypeJsonExtractor), value)
qType = repository.QuerytypeContextFull
value, err = queryprocessor.ParseDBType(qType)
assert.Nil(t, err)
assert.Equal(t, queryprocessor.Type(queryprocessor.TypeContextFull), value)
}
func TestToDBQueryType(t *testing.T) {
dbQueryType := queryprocessor.Type(queryprocessor.TypeJsonExtractor)
value, err := queryprocessor.ToDBQueryType(dbQueryType)
assert.Nil(t, err)
assert.Equal(t, repository.Querytype(repository.QuerytypeJsonExtractor), value)
dbQueryType = queryprocessor.Type(-1)
_, err = queryprocessor.ToDBQueryType(dbQueryType)
assert.EqualError(t, err, "invalid database query type")
dbQueryType = queryprocessor.Type(queryprocessor.TypeContextFull)
value, err = queryprocessor.ToDBQueryType(dbQueryType)
assert.Nil(t, err)
assert.Equal(t, repository.Querytype(repository.QuerytypeContextFull), value)
}
func TestToDBQueryTypeArray(t *testing.T) {
inArr := []queryprocessor.Type{
queryprocessor.TypeJsonExtractor,
queryprocessor.TypeContextFull,
}
value, err := queryprocessor.ToDBQueryTypeArray(inArr)
assert.Nil(t, err)
assert.Equal(t, []repository.Querytype{
repository.QuerytypeJsonExtractor,
repository.QuerytypeContextFull,
}, value)
inArr = []queryprocessor.Type{
queryprocessor.Type(-1),
}
_, err = queryprocessor.ToDBQueryTypeArray(inArr)
assert.EqualError(t, err, "invalid database query type")
}
func TestToDBNullQueryType(t *testing.T) {
dbQueryType := queryprocessor.Type(queryprocessor.TypeJsonExtractor)
value, err := queryprocessor.ToDBNullQueryType(dbQueryType)
assert.Nil(t, err)
assert.Equal(t, repository.NullQuerytype{Valid: true, Querytype: repository.QuerytypeJsonExtractor}, value)
dbQueryType = queryprocessor.Type(-1)
_, err = queryprocessor.ToDBNullQueryType(dbQueryType)
assert.EqualError(t, err, "invalid database query type")
dbQueryType = queryprocessor.Type(queryprocessor.TypeContextFull)
value, err = queryprocessor.ToDBNullQueryType(dbQueryType)
assert.Nil(t, err)
assert.Equal(t, repository.NullQuerytype{Valid: true, Querytype: repository.QuerytypeContextFull}, value)
}
+47
View File
@@ -0,0 +1,47 @@
package queryprocessor
import (
"context"
"queryorchestration/internal/query/result"
"github.com/google/uuid"
)
type Type int
const (
TypeJsonExtractor = iota
TypeContextFull
)
type Create struct {
Type Type
RequiredQueryIDs []uuid.UUID
Config string
}
type Update struct {
ID uuid.UUID
RequiredQueryIDs []uuid.UUID
Config string
}
type Query struct {
ID uuid.UUID
Type Type
Version int32
RequiredQueryIDs []uuid.UUID
Config string
}
type Creator interface {
Validate(ctx context.Context, entity *Create) error
}
type Updator interface {
Validate(ctx context.Context, current *Query, entity *Update) error
}
type Processor interface {
Process(ctx context.Context, query *Query, values []result.Value) (string, error)
}
+94
View File
@@ -0,0 +1,94 @@
package queryqueue
import (
"context"
"queryorchestration/internal/database"
queryprocessor "queryorchestration/internal/query/processor"
)
func (q *Queue) getUnsyncedQueries() {
for _, query := range q.collectorQueries {
if q.isQuerySynced(query) {
continue
}
q.Add(query)
}
}
func (q *Queue) isQuerySynced(query *queryprocessor.Query) bool {
for _, result := range q.results {
if result.QueryID == query.ID && result.QueryVersion == query.Version {
return true
}
}
return false
}
func (c *Queue) getCollectorQueries(ctx context.Context) error {
if c.collectorQueries != nil {
return nil
}
id := database.MustToDBUUID(c.collector.ID)
queries, err := c.db.Queries.GetCollectorQueries(ctx, id)
if err != nil {
return err
}
cleanQueries := make([]*queryprocessor.Query, len(queries))
for index, dbQuery := range queries {
cleanQuery, err := queryprocessor.ParseDBCollectorQuery(dbQuery)
if err != nil {
return err
}
cleanQueries[index] = cleanQuery
}
c.collectorQueries = cleanQueries
return nil
}
func (q *Queue) Add(qu *queryprocessor.Query) {
dependentQueries := []*queryprocessor.Query{}
requiredIndex := -1
if q.unsyncedQueue == nil {
q.unsyncedQueue = []*queryprocessor.Query{}
} else {
for index, entry := range q.unsyncedQueue {
if entry.ID == qu.ID {
return
}
for _, id := range qu.RequiredQueryIDs {
if entry.ID == id {
requiredIndex = index
break
}
}
}
}
for _, entry := range q.collectorQueries {
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([]*queryprocessor.Query{qu}, (q.unsyncedQueue)[requiredIndex+1:]...)...)
} else {
q.unsyncedQueue = append([]*queryprocessor.Query{qu}, q.unsyncedQueue...)
}
for _, entry := range dependentQueries {
q.Add(entry)
}
}
+139
View File
@@ -0,0 +1,139 @@
package queryqueue
import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/job/collector"
queryprocessor "queryorchestration/internal/query/processor"
"queryorchestration/internal/query/result"
"testing"
"github.com/google/uuid"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestGetUnsyncedQueries(t *testing.T) {
queryOne := &queryprocessor.Query{
ID: uuid.New(),
Version: int32(1),
}
svc := Queue{
collectorQueries: []*queryprocessor.Query{
queryOne,
},
results: []*result.Result{
{ID: uuid.New(), QueryID: queryOne.ID, QueryVersion: queryOne.Version},
},
}
svc.getUnsyncedQueries()
assert.EqualExportedValues(t, []*queryprocessor.Query(nil), svc.unsyncedQueue)
svc.results = []*result.Result{}
svc.unsyncedQueue = []*queryprocessor.Query{}
svc.getUnsyncedQueries()
assert.EqualExportedValues(t, []*queryprocessor.Query{queryOne}, svc.unsyncedQueue)
}
func TestGetCollectorQueries(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
svc := Queue{
db: db,
collector: &collector.Collector{
ID: uuid.New(),
},
}
dbCollectorID := database.MustToDBUUID(svc.collector.ID)
collectorQueries := []*queryprocessor.Query{
{ID: uuid.New(), Type: queryprocessor.TypeContextFull, RequiredQueryIDs: []uuid.UUID{}, Version: int32(1)},
}
rows := pgxmock.NewRows([]string{"collectorId", "queryId", "type", "queryVersion", "requiredIds"})
for _, q := range collectorQueries {
dbID := database.MustToDBUUID(q.ID)
dbReqIDs := database.MustToDBUUIDArray(q.RequiredQueryIDs)
ty, err := queryprocessor.ToDBNullQueryType(q.Type)
assert.Nil(t, err)
rows = rows.
AddRow(dbCollectorID, dbID, ty, &q.Version, dbReqIDs)
}
pool.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorID).WillReturnRows(rows)
err = svc.getCollectorQueries(ctx)
assert.Nil(t, err)
assert.EqualExportedValues(t, collectorQueries, svc.collectorQueries)
}
func TestIsQuerySynced(t *testing.T) {
query := &queryprocessor.Query{
ID: uuid.New(),
Version: int32(1),
}
svc := Queue{
results: []*result.Result{
{QueryID: query.ID, QueryVersion: query.Version},
},
}
isSynced := svc.isQuerySynced(query)
assert.True(t, isSynced)
}
func TestIsQuerySyncedNoResult(t *testing.T) {
query := &queryprocessor.Query{
ID: uuid.New(),
Version: int32(1),
}
svc := Queue{
results: []*result.Result{},
}
isSynced := svc.isQuerySynced(query)
assert.False(t, isSynced)
}
func TestIsQuerySyncedOldResult(t *testing.T) {
query := &queryprocessor.Query{
ID: uuid.New(),
Version: int32(1),
}
svc := Queue{
results: []*result.Result{
{QueryID: query.ID, QueryVersion: query.Version - 1},
},
}
isSynced := svc.isQuerySynced(query)
assert.False(t, isSynced)
}
func TestIsQuerySyncedNewResult(t *testing.T) {
query := &queryprocessor.Query{
ID: uuid.New(),
Version: int32(1),
}
svc := Queue{
results: []*result.Result{
{QueryID: query.ID, QueryVersion: query.Version + 1},
},
}
isSynced := svc.isQuerySynced(query)
assert.False(t, isSynced)
}
+69
View File
@@ -0,0 +1,69 @@
package queryqueue
import (
"context"
"queryorchestration/internal/database"
queryprocessor "queryorchestration/internal/query/processor"
"queryorchestration/internal/query/result"
"github.com/jackc/pgx/v5/pgtype"
)
func (q *Queue) Execute(ctx context.Context) error {
if q.unsyncedQueue == nil {
return nil
}
for _, query := range q.unsyncedQueue {
err := q.executeQuery(ctx, query)
if err != nil {
return err
}
}
q.unsyncedQueue = nil
return nil
}
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 {
queryVersion = entry.Version
break
}
}
for _, entry := range q.results {
if entry.QueryID == id && entry.QueryVersion == queryVersion {
resultIDs[index] = database.MustToDBUUID(entry.ID)
break
}
}
}
values, err := q.db.Queries.ListResultValuesByID(ctx, resultIDs)
if err != nil {
return err
}
cleanValues := make([]result.Value, len(values))
for index, r := range values {
cleanValue, err := q.getResultValue(r)
if err != nil {
return err
}
cleanValues[index] = cleanValue
}
err = q.setResult(ctx, qu, cleanValues)
if err != nil {
return err
}
return nil
}
+179
View File
@@ -0,0 +1,179 @@
package queryqueue_test
import (
"context"
"fmt"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/job/collector"
queryprocessor "queryorchestration/internal/query/processor"
queryqueue "queryorchestration/internal/query/queue"
"queryorchestration/internal/query/result"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestExecute(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
jobID := uuid.New()
dbJobID := database.MustToDBUUID(jobID)
collectorID := uuid.New()
dbCollectorID := database.MustToDBUUID(collectorID)
pool.ExpectQuery("name: GetCollectorFromJobID :one").WithArgs(dbJobID).
WillReturnRows(
pgxmock.NewRows([]string{"id", "jobId", "minCleanVersion", "minTextVersion"}).
AddRow(dbCollectorID, dbJobID, int32(1), int32(1)),
)
coll, err := collector.NewByJobId(ctx, db, jobID)
assert.Nil(t, err)
queryOneID := uuid.New()
queryOneVersion := int32(1)
queryTwoID := uuid.New()
queryTwoVersion := int32(2)
queryThreeID := uuid.New()
queryThreeVersion := int32(3)
queryFourID := uuid.New()
queryFourVersion := int32(4)
queryFiveID := uuid.New()
queryFiveVersion := int32(5)
querySixID := uuid.New()
querySixVersion := int32(6)
contextID := uuid.New()
contextVersion := int32(1)
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", "queryVersion", "requiredIds"})
for _, q := range collectorQueries {
dbID := database.MustToDBUUID(q.ID)
dbReqIDs := database.MustToDBUUIDArray(q.RequiredQueryIDs)
ty, err := queryprocessor.ToDBNullQueryType(q.Type)
assert.Nil(t, err)
rows = rows.
AddRow(dbCollectorID, dbID, ty, &q.Version, dbReqIDs)
}
pool.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorID).WillReturnRows(rows)
contextResultID := uuid.New()
results := []*result.Result{
{ID: contextResultID, QueryID: contextID, QueryVersion: contextVersion},
{ID: uuid.New(), QueryID: queryFourID, QueryVersion: queryFourVersion},
{ID: uuid.New(), QueryID: querySixID, QueryVersion: querySixVersion - 1},
{ID: uuid.New(), QueryID: queryOneID, QueryVersion: queryOneVersion - 1},
}
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()
cleanVersion := int32(1)
textVersion := int32(1)
q, err := queryqueue.New(ctx, db, coll, results, docID, cleanVersion, textVersion)
assert.Nil(t, err)
assert.Equal(t, expectedQueries, q.GetQueue())
keyLayerOne := "key"
keyLayerTwo := "key5"
valueLayerTwo := "value"
valueLayerOne := fmt.Sprintf("{\"%s\":\"%s\"}", keyLayerTwo, valueLayerTwo)
valueContext := fmt.Sprintf("{\"%s\":%s}", keyLayerOne, valueLayerOne)
pool.ExpectQuery("name: ListResultValuesByID :many").WithArgs([]pgtype.UUID{database.MustToDBUUID(contextResultID)}).WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "value"}).
AddRow(database.MustToDBUUID(contextResultID), database.MustToDBUUID(contextID), valueContext),
)
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(querySixID), querySixVersion).WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(fmt.Sprintf("{\"path\":\"%s\"}", keyLayerOne))),
)
pool.ExpectQuery("name: SetResult :one").WithArgs(database.MustToDBUUID(querySixID), database.MustToDBUUID(docID), valueLayerOne, cleanVersion, textVersion, querySixVersion).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).AddRow(pgtype.UUID{}),
)
pool.ExpectQuery("name: ListResultValuesByID :many").WithArgs(pgxmock.AnyArg()).WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "value"}).
AddRow(pgtype.UUID{}, database.MustToDBUUID(querySixID), valueLayerOne),
)
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(queryFiveID), queryFiveVersion).WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(fmt.Sprintf("{\"path\":\"%s\"}", keyLayerTwo))),
)
pool.ExpectQuery("name: SetResult :one").WithArgs(database.MustToDBUUID(queryFiveID), database.MustToDBUUID(docID), valueLayerTwo, cleanVersion, textVersion, queryFiveVersion).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).AddRow(pgtype.UUID{}),
)
pool.ExpectQuery("name: ListResultValuesByID :many").WithArgs(pgxmock.AnyArg()).WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "value"}).
AddRow(database.MustToDBUUID(contextResultID), database.MustToDBUUID(contextID), valueContext),
)
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(queryOneID), queryOneVersion).WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(fmt.Sprintf("{\"path\":\"%s\"}", keyLayerOne))),
)
pool.ExpectQuery("name: SetResult :one").WithArgs(database.MustToDBUUID(queryOneID), database.MustToDBUUID(docID), valueLayerOne, cleanVersion, textVersion, queryOneVersion).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).AddRow(pgtype.UUID{}),
)
pool.ExpectQuery("name: ListResultValuesByID :many").WithArgs(pgxmock.AnyArg()).WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "value"}).
AddRow(pgtype.UUID{}, database.MustToDBUUID(queryOneID), valueLayerOne),
)
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(queryThreeID), queryThreeVersion).WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(fmt.Sprintf("{\"path\":\"%s\"}", keyLayerTwo))),
)
pool.ExpectQuery("name: SetResult :one").WithArgs(database.MustToDBUUID(queryThreeID), database.MustToDBUUID(docID), valueLayerTwo, cleanVersion, textVersion, queryThreeVersion).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).AddRow(pgtype.UUID{}),
)
pool.ExpectQuery("name: ListResultValuesByID :many").WithArgs(pgxmock.AnyArg()).WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "value"}).
AddRow(pgtype.UUID{}, database.MustToDBUUID(queryOneID), valueLayerOne),
)
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(queryTwoID), queryTwoVersion).WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(fmt.Sprintf("{\"path\":\"%s\"}", keyLayerTwo))),
)
pool.ExpectQuery("name: SetResult :one").WithArgs(database.MustToDBUUID(queryTwoID), database.MustToDBUUID(docID), valueLayerTwo, cleanVersion, textVersion, queryTwoVersion).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).AddRow(pgtype.UUID{}),
)
err = q.Execute(ctx)
assert.Nil(t, err)
}
@@ -0,0 +1,94 @@
package queryqueue
import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/query/processor"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestExecute(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
expectedQueries := []*queryprocessor.Query{
{ID: uuid.New(), Type: queryprocessor.TypeContextFull, RequiredQueryIDs: []uuid.UUID{}, Version: int32(1)},
{ID: uuid.New(), Type: queryprocessor.TypeContextFull, RequiredQueryIDs: []uuid.UUID{}, Version: int32(2)},
}
q := &Queue{
unsyncedQueue: expectedQueries,
db: db,
documentId: uuid.New(),
cleanVersion: int32(1),
textVersion: int32(2),
}
pool.ExpectQuery("name: ListResultValuesByID :many").WithArgs([]pgtype.UUID{}).WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "value"}),
)
pool.ExpectQuery("name: SetResult :one").WithArgs(database.MustToDBUUID(expectedQueries[0].ID), database.MustToDBUUID(q.documentId), pgxmock.AnyArg(), q.cleanVersion, q.textVersion, expectedQueries[0].Version).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).AddRow(pgtype.UUID{}),
)
pool.ExpectQuery("name: ListResultValuesByID :many").WithArgs([]pgtype.UUID{}).WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "value"}),
)
pool.ExpectQuery("name: SetResult :one").WithArgs(database.MustToDBUUID(expectedQueries[1].ID), database.MustToDBUUID(q.documentId), pgxmock.AnyArg(), q.cleanVersion, q.textVersion, expectedQueries[1].Version).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).AddRow(pgtype.UUID{}),
)
err = q.Execute(ctx)
assert.Nil(t, err)
}
func TestExecuteQuery(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
qu := &queryprocessor.Query{ID: uuid.New(), Type: queryprocessor.TypeContextFull, RequiredQueryIDs: []uuid.UUID{}, Version: int32(1)}
q := &Queue{
db: db,
documentId: uuid.New(),
cleanVersion: int32(1),
textVersion: int32(2),
}
pool.ExpectQuery("name: ListResultValuesByID :many").WithArgs([]pgtype.UUID{}).WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "value"}),
)
pool.ExpectQuery("name: SetResult :one").WithArgs(database.MustToDBUUID(qu.ID), database.MustToDBUUID(q.documentId), pgxmock.AnyArg(), q.cleanVersion, q.textVersion, qu.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).AddRow(pgtype.UUID{}),
)
err = q.executeQuery(ctx, qu)
assert.Nil(t, err)
}
+73
View File
@@ -0,0 +1,73 @@
package queryqueue
import (
"context"
"fmt"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/query/processor"
"queryorchestration/internal/query/result"
contextfull "queryorchestration/internal/query/types/contextFull"
jsonextractor "queryorchestration/internal/query/types/jsonExtractor"
)
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
}
value, err := processor.Process(ctx, qu, resultValues)
if err != nil {
return err
}
id, err := result.Store(ctx, q.db.Queries, &result.ResultStore{
QueryID: qu.ID,
DocumentID: q.documentId,
Value: value,
CleanVersion: q.cleanVersion,
TextVersion: q.textVersion,
QueryVersion: qu.Version,
})
if err != nil {
return err
}
q.results = append(q.results, &result.Result{
ID: id,
QueryID: qu.ID,
QueryVersion: qu.Version,
})
return nil
}
func (q *Queue) getProcessor(queryType queryprocessor.Type) (queryprocessor.Processor, error) {
switch queryType {
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")
}
}
func (q *Queue) getResultValue(res *repository.ListResultValuesByIDRow) (result.Value, error) {
var queryType queryprocessor.Type
for _, qu := range q.collectorQueries {
if qu.ID == database.MustToUUID(res.Queryid) {
queryType = qu.Type
}
}
switch queryType {
case queryprocessor.TypeJsonExtractor:
return jsonextractor.NewResult(res.Value), nil
case queryprocessor.TypeContextFull:
return contextfull.NewResult(res.Value), nil
default:
return nil, fmt.Errorf("attempting to process invalid query type")
}
}
@@ -0,0 +1,74 @@
package queryqueue
import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/query/processor"
"queryorchestration/internal/query/result"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestSetResult(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
q := &Queue{
db: db,
documentId: uuid.New(),
cleanVersion: int32(1),
textVersion: int32(2),
}
qu := &queryprocessor.Query{ID: uuid.New(), Type: queryprocessor.TypeContextFull, RequiredQueryIDs: []uuid.UUID{}, Version: int32(1)}
resultValues := []result.Value{}
pool.ExpectQuery("name: SetResult :one").WithArgs(database.MustToDBUUID(qu.ID), database.MustToDBUUID(q.documentId), pgxmock.AnyArg(), q.cleanVersion, q.textVersion, qu.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).AddRow(pgtype.UUID{}),
)
err = q.setResult(ctx, qu, resultValues)
assert.Nil(t, err)
}
func TestGetProcessor(t *testing.T) {
q := Queue{}
qType := queryprocessor.Type(queryprocessor.TypeContextFull)
processor, err := q.getProcessor(qType)
assert.Nil(t, err)
assert.NotNil(t, processor)
}
func TestGetResultValue(t *testing.T) {
result := &repository.ListResultValuesByIDRow{
Queryid: database.MustToDBUUID(uuid.New()),
Value: "EXAMPLE_VALUE",
}
q := &Queue{
collectorQueries: []*queryprocessor.Query{
{ID: database.MustToUUID(result.Queryid), Type: queryprocessor.TypeContextFull},
},
}
value, err := q.getResultValue(result)
assert.Nil(t, err)
assert.NotNil(t, value)
}
+46
View File
@@ -0,0 +1,46 @@
package queryqueue
import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/job/collector"
queryprocessor "queryorchestration/internal/query/processor"
"queryorchestration/internal/query/result"
"github.com/google/uuid"
)
type Queue struct {
unsyncedQueue []*queryprocessor.Query
collectorQueries []*queryprocessor.Query
results []*result.Result
collector *collector.Collector
db *database.Connection
cleanVersion int32
textVersion int32
documentId uuid.UUID
}
func New(ctx context.Context, db *database.Connection, coll *collector.Collector, results []*result.Result, docId uuid.UUID, cleanVersion int32, textVersion int32) (*Queue, error) {
queue := Queue{
db: db,
results: results,
collector: coll,
documentId: docId,
cleanVersion: cleanVersion,
textVersion: textVersion,
}
err := queue.getCollectorQueries(ctx)
if err != nil {
return nil, err
}
queue.getUnsyncedQueries()
return &queue, nil
}
func (q *Queue) GetQueue() []*queryprocessor.Query {
return q.unsyncedQueue
}
+144
View File
@@ -0,0 +1,144 @@
package queryqueue_test
import (
"context"
"errors"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/job/collector"
queryprocessor "queryorchestration/internal/query/processor"
queryqueue "queryorchestration/internal/query/queue"
"queryorchestration/internal/query/result"
"testing"
"github.com/google/uuid"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestService(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
jobID := uuid.New()
dbJobID := database.MustToDBUUID(jobID)
collectorID := uuid.New()
dbCollectorID := database.MustToDBUUID(collectorID)
pool.ExpectQuery("name: GetCollectorFromJobID :one").WithArgs(dbJobID).
WillReturnRows(
pgxmock.NewRows([]string{"id", "jobId", "minCleanVersion", "minTextVersion"}).
AddRow(dbCollectorID, dbJobID, int32(1), int32(1)),
)
coll, err := collector.NewByJobId(ctx, db, jobID)
assert.Nil(t, err)
queryOneID := uuid.New()
queryOneVersion := int32(1)
queryTwoID := uuid.New()
queryTwoVersion := int32(2)
queryThreeID := uuid.New()
queryThreeVersion := int32(3)
queryFourID := uuid.New()
queryFourVersion := int32(4)
queryFiveID := uuid.New()
queryFiveVersion := int32(5)
querySixID := uuid.New()
querySixVersion := int32(6)
contextID := uuid.New()
contextVersion := int32(1)
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", "queryVersion", "requiredIds"})
for _, q := range collectorQueries {
dbID := database.MustToDBUUID(q.ID)
dbReqIDs := database.MustToDBUUIDArray(q.RequiredQueryIDs)
ty, err := queryprocessor.ToDBNullQueryType(q.Type)
assert.Nil(t, err)
rows = rows.
AddRow(dbCollectorID, dbID, ty, &q.Version, dbReqIDs)
}
pool.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorID).WillReturnRows(rows)
contextResultID := uuid.New()
results := []*result.Result{
{ID: contextResultID, QueryID: contextID, QueryVersion: contextVersion},
{ID: uuid.New(), QueryID: queryFourID, QueryVersion: queryFourVersion},
{ID: uuid.New(), QueryID: querySixID, QueryVersion: querySixVersion - 1},
{ID: uuid.New(), QueryID: queryOneID, QueryVersion: queryOneVersion - 1},
}
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()
cleanVersion := int32(1)
textVersion := int32(1)
q, err := queryqueue.New(ctx, db, coll, results, docID, cleanVersion, textVersion)
assert.Nil(t, err)
assert.Equal(t, expectedQueries, q.GetQueue())
}
func TestQueueFail(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
jobID := uuid.New()
dbJobID := database.MustToDBUUID(jobID)
collectorID := uuid.New()
dbCollectorID := database.MustToDBUUID(collectorID)
pool.ExpectQuery("name: GetCollectorFromJobID :one").WithArgs(dbJobID).
WillReturnRows(
pgxmock.NewRows([]string{"id", "jobId", "minCleanVersion", "minTextVersion"}).
AddRow(dbCollectorID, dbJobID, int32(1), int32(1)),
)
coll, err := collector.NewByJobId(ctx, db, jobID)
assert.Nil(t, err)
dbErr := "database failure"
pool.ExpectQuery("name: GetCollectorQueries :many").WithArgs(dbCollectorID).
WillReturnError(errors.New(dbErr))
results := []*result.Result{}
docID := uuid.New()
cleanVersion := int32(1)
textVersion := int32(1)
_, err = queryqueue.New(ctx, db, coll, results, docID, cleanVersion, textVersion)
assert.EqualError(t, err, dbErr)
}
+14
View File
@@ -0,0 +1,14 @@
package result
import (
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
)
func Parse(dbQuery *repository.ListResultsByDocumentIDRow) *Result {
return &Result{
ID: database.MustToUUID(dbQuery.ID),
QueryID: database.MustToUUID(dbQuery.Queryid),
QueryVersion: dbQuery.Queryversion,
}
}
+24
View File
@@ -0,0 +1,24 @@
package result_test
import (
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query/result"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
"github.com/stretchr/testify/assert"
)
func TestParseResultValue(t *testing.T) {
dbResult := repository.ListResultsByDocumentIDRow{
ID: pgtype.UUID{},
Queryid: pgtype.UUID{},
Queryversion: int32(1),
}
value := result.Parse(&dbResult)
assert.Equal(t, dbResult.Queryversion, value.QueryVersion)
assert.Equal(t, uuid.Nil, value.ID)
assert.Equal(t, uuid.Nil, value.QueryID)
}
+46
View File
@@ -0,0 +1,46 @@
package result
import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"github.com/google/uuid"
)
type Result struct {
ID uuid.UUID
QueryID uuid.UUID
QueryVersion int32
}
type Value interface {
GetValue(ctx context.Context) (string, error)
}
type ResultStore struct {
QueryID uuid.UUID
DocumentID uuid.UUID
Value string
CleanVersion int32
TextVersion int32
QueryVersion int32
}
func Store(ctx context.Context, dbQueries *repository.Queries, res *ResultStore) (uuid.UUID, error) {
dbId, err := dbQueries.SetResult(ctx, &repository.SetResultParams{
Queryid: database.MustToDBUUID(res.QueryID),
Documentid: database.MustToDBUUID(res.DocumentID),
Value: res.Value,
Cleanversion: res.CleanVersion,
Textversion: res.TextVersion,
Queryversion: res.QueryVersion,
})
if err != nil {
return uuid.Nil, err
}
id := database.MustToUUID(dbId)
return id, nil
}
+50
View File
@@ -0,0 +1,50 @@
package result_test
import (
"context"
"errors"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query/result"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestStore(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
resultStore := result.ResultStore{
QueryID: uuid.New(),
DocumentID: uuid.New(),
Value: "val",
CleanVersion: int32(1),
TextVersion: int32(1),
QueryVersion: int32(1),
}
pool.ExpectQuery("name: SetResult :one").WithArgs(database.MustToDBUUID(resultStore.QueryID), database.MustToDBUUID(resultStore.DocumentID), resultStore.Value, resultStore.CleanVersion, resultStore.TextVersion, resultStore.QueryVersion).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).AddRow(pgtype.UUID{}),
)
id, err := result.Store(ctx, queries, &resultStore)
assert.Nil(t, err)
assert.NotNil(t, id)
dbErr := "database failing"
pool.ExpectQuery("name: SetResult :one").WithArgs(database.MustToDBUUID(resultStore.QueryID), database.MustToDBUUID(resultStore.DocumentID), resultStore.Value, resultStore.CleanVersion, resultStore.TextVersion, resultStore.QueryVersion).
WillReturnError(errors.New(dbErr))
id, err = result.Store(ctx, queries, &resultStore)
assert.EqualError(t, err, dbErr)
assert.Equal(t, uuid.Nil, id)
}
@@ -0,0 +1,21 @@
package contextfull
import (
"context"
"queryorchestration/internal/database"
queryprocessor "queryorchestration/internal/query/processor"
)
type Creator struct {
db *database.Connection
}
func NewCreator(db *database.Connection) Creator {
return Creator{db}
}
func (s Creator) Validate(ctx context.Context, entity *queryprocessor.Create) error {
// TODO
// Type, RequiredQueryIDs, Config
return nil
}
@@ -0,0 +1,40 @@
package contextfull_test
import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/query/processor"
contextfull "queryorchestration/internal/query/types/contextFull"
"testing"
"github.com/google/uuid"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestCreatorValidate(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
svc := contextfull.NewCreator(db)
assert.NotNil(t, svc)
entity := &queryprocessor.Create{
Type: queryprocessor.TypeContextFull,
RequiredQueryIDs: []uuid.UUID{},
Config: "",
}
err = svc.Validate(ctx, entity)
assert.Nil(t, err)
}
@@ -0,0 +1,38 @@
package contextfull_test
import (
"context"
queryprocessor "queryorchestration/internal/query/processor"
"queryorchestration/internal/query/result"
contextfull "queryorchestration/internal/query/types/contextFull"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
)
func TestContextFull(t *testing.T) {
ctx := context.Background()
extractor := contextfull.NewExtractor()
query := &queryprocessor.Query{
ID: uuid.New(),
Type: queryprocessor.TypeJsonExtractor,
RequiredQueryIDs: []uuid.UUID{},
Version: int32(1),
}
values := []result.Value{}
value, err := extractor.Process(ctx, query, values)
assert.Nil(t, err)
assert.Equal(t, "", value)
values = []result.Value{
contextfull.NewResult("example_result"),
}
_, err = extractor.Process(ctx, query, values)
assert.EqualError(t, err, "no requirements expected")
}
@@ -0,0 +1,18 @@
package contextfull
import (
"context"
)
type Result struct {
value string
}
func NewResult(value string) Result {
return Result{value}
}
func (r Result) GetValue(ctx context.Context) (string, error) {
// TODO - get value from s3
return r.value, nil
}
@@ -0,0 +1,24 @@
package contextfull
import (
"context"
"errors"
queryprocessor "queryorchestration/internal/query/processor"
"queryorchestration/internal/query/result"
)
type Extractor struct {
}
func NewExtractor() Extractor {
return Extractor{}
}
func (e Extractor) Process(ctx context.Context, query *queryprocessor.Query, values []result.Value) (string, error) {
if len(values) > 0 {
return "", errors.New("no requirements expected")
}
// TODO
return "", nil
}
@@ -0,0 +1,21 @@
package contextfull
import (
"context"
"queryorchestration/internal/database"
queryprocessor "queryorchestration/internal/query/processor"
)
type Updator struct {
db *database.Connection
}
func NewUpdator(db *database.Connection) Updator {
return Updator{db}
}
func (s Updator) Validate(ctx context.Context, current *queryprocessor.Query, entity *queryprocessor.Update) error {
// TODO
// Type, RequiredQueryIDs, Config
return nil
}
@@ -0,0 +1,48 @@
package contextfull_test
import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/query/processor"
contextfull "queryorchestration/internal/query/types/contextFull"
"testing"
"github.com/google/uuid"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestUpdatorValidate(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
svc := contextfull.NewUpdator(db)
assert.NotNil(t, svc)
current := &queryprocessor.Query{
ID: uuid.New(),
Type: queryprocessor.TypeContextFull,
Version: int32(1),
RequiredQueryIDs: []uuid.UUID{},
Config: "",
}
entity := &queryprocessor.Update{
ID: current.ID,
RequiredQueryIDs: []uuid.UUID{},
Config: "",
}
err = svc.Validate(ctx, current, entity)
assert.Nil(t, err)
}
@@ -0,0 +1,20 @@
package jsonextractor
import (
"context"
"queryorchestration/internal/database"
queryprocessor "queryorchestration/internal/query/processor"
)
type Creator struct {
db *database.Connection
}
func NewCreator(db *database.Connection) Creator {
return Creator{db}
}
func (s Creator) Validate(ctx context.Context, entity *queryprocessor.Create) error {
// TODO
return nil
}
@@ -0,0 +1,40 @@
package jsonextractor_test
import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/query/processor"
jsonextractor "queryorchestration/internal/query/types/jsonExtractor"
"testing"
"github.com/google/uuid"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestCreatorValidate(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
svc := jsonextractor.NewCreator(db)
assert.NotNil(t, svc)
entity := &queryprocessor.Create{
Type: queryprocessor.TypeJsonExtractor,
RequiredQueryIDs: []uuid.UUID{},
Config: "",
}
err = svc.Validate(ctx, entity)
assert.Nil(t, err)
}
@@ -0,0 +1,220 @@
package jsonextractor_test
import (
"context"
"fmt"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/query/processor"
"queryorchestration/internal/query/result"
contextfull "queryorchestration/internal/query/types/contextFull"
jsonextractor "queryorchestration/internal/query/types/jsonExtractor"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestJSONProcess(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
extractor := jsonextractor.NewExtractor(db)
query := &queryprocessor.Query{
ID: uuid.New(),
Type: queryprocessor.TypeJsonExtractor,
RequiredQueryIDs: []uuid.UUID{},
Version: int32(1),
}
entryValue := "value"
jsonString := fmt.Sprintf("{\"key\": \"%s\"}", entryValue)
values := []result.Value{
contextfull.NewResult(jsonString),
}
config := "{\"path\":\"key\"}"
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(query.ID), query.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(config)),
)
value, err := extractor.Process(ctx, query, values)
assert.Nil(t, err)
assert.Equal(t, entryValue, value)
entryValue = ""
jsonString = fmt.Sprintf("{\"key\": \"%s\"}", entryValue)
values = []result.Value{
contextfull.NewResult(jsonString),
}
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(query.ID), query.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(config)),
)
value, err = extractor.Process(ctx, query, values)
assert.Nil(t, err)
assert.Equal(t, entryValue, value)
entryValue = "1"
jsonString = fmt.Sprintf("{\"key\": %s", entryValue)
values = []result.Value{
contextfull.NewResult(jsonString),
}
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(query.ID), query.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(config)),
)
value, err = extractor.Process(ctx, query, values)
assert.Nil(t, err)
assert.Equal(t, entryValue, value)
}
func TestJSONProcessJSON(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
extractor := jsonextractor.NewExtractor(db)
query := &queryprocessor.Query{
ID: uuid.New(),
Type: queryprocessor.TypeJsonExtractor,
RequiredQueryIDs: []uuid.UUID{},
Version: int32(1),
}
entryValue := "value"
jsonString := fmt.Sprintf("{\"key\": \"%s\"}", entryValue)
values := []result.Value{
contextfull.NewResult(jsonString),
}
config := "{\"path\":\"invalid_key\"}"
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(query.ID), query.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(config)),
)
value, err := extractor.Process(ctx, query, values)
assert.EqualError(t, err, "JSON path does not exist: invalid_key")
assert.Empty(t, value)
config = ""
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(query.ID), query.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(config)),
)
value, err = extractor.Process(ctx, query, values)
assert.EqualError(t, err, "unexpected end of JSON input")
assert.Empty(t, value)
config = "{\"path\":\"\"}"
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(query.ID), query.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(config)),
)
value, err = extractor.Process(ctx, query, values)
assert.EqualError(t, err, "JSON path does not exist: ")
assert.Empty(t, value)
config = "{\"path\":}"
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(query.ID), query.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}).
AddRow(pgtype.UUID{}, []byte(config)),
)
value, err = extractor.Process(ctx, query, values)
assert.EqualError(t, err, "invalid character '}' looking for beginning of value")
assert.Empty(t, value)
pool.ExpectQuery("name: GetQueryConfig :one").WithArgs(database.MustToDBUUID(query.ID), query.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id", "config"}),
)
value, err = extractor.Process(ctx, query, values)
assert.EqualError(t, err, "no rows in result set")
assert.Empty(t, value)
}
func TestJSONProcessResults(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
extractor := jsonextractor.NewExtractor(db)
query := &queryprocessor.Query{
ID: uuid.New(),
Type: queryprocessor.TypeJsonExtractor,
RequiredQueryIDs: []uuid.UUID{},
Version: int32(1),
}
results := []result.Value{}
value, err := extractor.Process(ctx, query, results)
assert.EqualError(t, err, "JSON Extraction requires 1 result")
assert.Empty(t, value)
results = []result.Value{
contextfull.NewResult(""),
contextfull.NewResult(""),
}
value, err = extractor.Process(ctx, query, results)
assert.EqualError(t, err, "JSON Extraction requires 1 result")
assert.Empty(t, value)
results = []result.Value{
contextfull.NewResult(""),
contextfull.NewResult(""),
contextfull.NewResult(""),
}
value, err = extractor.Process(ctx, query, results)
assert.EqualError(t, err, "JSON Extraction requires 1 result")
assert.Empty(t, value)
}
@@ -0,0 +1,17 @@
package jsonextractor
import (
"context"
)
type Result struct {
value string
}
func NewResult(value string) Result {
return Result{value}
}
func (r Result) GetValue(ctx context.Context) (string, error) {
return r.value, nil
}
@@ -0,0 +1,62 @@
package jsonextractor
import (
"context"
"encoding/json"
"fmt"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/query/processor"
"queryorchestration/internal/query/result"
"github.com/tidwall/gjson"
)
type Extractor struct {
db *database.Connection
}
type Config struct {
Path string `json:"path"`
}
func NewExtractor(db *database.Connection) Extractor {
return Extractor{db}
}
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")
}
value, err := values[0].GetValue(ctx)
if err != nil {
return "", err
}
byteConfig, err := e.db.Queries.GetQueryConfig(ctx, &repository.GetQueryConfigParams{
Queryid: database.MustToDBUUID(query.ID),
Addedversion: query.Version,
})
if err != nil {
return "", err
}
var config Config
err = json.Unmarshal(byteConfig.Config, &config)
if err != nil {
return "", err
}
return e.extract(value, config.Path)
}
func (e *Extractor) extract(jsonString string, path string) (string, error) {
value := gjson.Get(jsonString, path)
if !value.Exists() {
return "", fmt.Errorf("JSON path does not exist: %s", path)
}
return value.String(), nil
}
@@ -0,0 +1,20 @@
package jsonextractor
import (
"context"
"queryorchestration/internal/database"
queryprocessor "queryorchestration/internal/query/processor"
)
type Updator struct {
db *database.Connection
}
func NewUpdator(db *database.Connection) Updator {
return Updator{db}
}
func (s Updator) Validate(ctx context.Context, current *queryprocessor.Query, entity *queryprocessor.Update) error {
// TODO
return nil
}
@@ -0,0 +1,48 @@
package jsonextractor_test
import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/query/processor"
jsonextractor "queryorchestration/internal/query/types/jsonExtractor"
"testing"
"github.com/google/uuid"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
)
func TestUpdatorValidate(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
if err != nil {
t.Fatalf("failed to open pgxmock database: %v", err)
}
queries := repository.New(pool)
db := &database.Connection{
Queries: queries,
Pool: pool,
}
svc := jsonextractor.NewUpdator(db)
assert.NotNil(t, svc)
current := &queryprocessor.Query{
ID: uuid.New(),
Type: queryprocessor.TypeJsonExtractor,
Version: int32(1),
RequiredQueryIDs: []uuid.UUID{},
Config: "",
}
entity := &queryprocessor.Update{
ID: current.ID,
RequiredQueryIDs: []uuid.UUID{},
Config: "",
}
err = svc.Validate(ctx, current, entity)
assert.Nil(t, err)
}
+3 -3
View File
@@ -3,9 +3,9 @@ package query
import (
"context"
"fmt"
contextfull "queryorchestration/internal/contextFull"
jsonextractor "queryorchestration/internal/jsonExtractor"
queryprocessor "queryorchestration/internal/queryProcessor"
queryprocessor "queryorchestration/internal/query/processor"
contextfull "queryorchestration/internal/query/types/contextFull"
jsonextractor "queryorchestration/internal/query/types/jsonExtractor"
)
func (s *Service) Update(ctx context.Context, entity *queryprocessor.Update) error {
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/query"
queryprocessor "queryorchestration/internal/queryProcessor"
queryprocessor "queryorchestration/internal/query/processor"
"testing"
"github.com/google/uuid"
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"context"
"queryorchestration/internal/database"
"queryorchestration/internal/database/repository"
queryprocessor "queryorchestration/internal/queryProcessor"
queryprocessor "queryorchestration/internal/query/processor"
"testing"
"github.com/google/uuid"