NOISSUE - Add multi-publisher filter to readers PageMetadata (#3550)
Property Based Tests / api-test (push) Has been cancelled
Continuous Delivery / lint-and-build (push) Has been cancelled
Deploy GitHub Pages / swagger-ui (push) Has been cancelled
CI Pipeline / Lint Proto (push) Has been cancelled
CI Pipeline / Detect Changes (push) Has been cancelled
Continuous Delivery / Build and Push Docker Images (push) Has been cancelled
CI Pipeline / lint-and-build (push) Has been cancelled
CI Pipeline / Test ${{ matrix.module }} (push) Has been cancelled
CI Pipeline / Upload Coverage (push) Has been cancelled

Signed-off-by: fbugarski <filipbugarski@gmail.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Filip Bugarski
2026-07-16 11:04:56 +02:00
committed by GitHub
parent 513a84361b
commit 14d6db9684
7 changed files with 91 additions and 61 deletions
+14 -3
View File
@@ -4,7 +4,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.11
// protoc v6.33.0
// protoc v7.35.1
// source: readers/v1/readers.proto
package v1
@@ -104,6 +104,7 @@ type PageMetadata struct {
Format string `protobuf:"bytes,17,opt,name=format,proto3" json:"format,omitempty"`
Order string `protobuf:"bytes,18,opt,name=order,proto3" json:"order,omitempty"`
Dir string `protobuf:"bytes,19,opt,name=dir,proto3" json:"dir,omitempty"`
Publishers []string `protobuf:"bytes,20,rep,name=publishers,proto3" json:"publishers,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -271,6 +272,13 @@ func (x *PageMetadata) GetDir() string {
return ""
}
func (x *PageMetadata) GetPublishers() []string {
if x != nil {
return x.Publishers
}
return nil
}
type ReadMessagesRes struct {
state protoimpl.MessageState `protogen:"open.v1"`
Total uint64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
@@ -722,7 +730,7 @@ var File_readers_v1_readers_proto protoreflect.FileDescriptor
const file_readers_v1_readers_proto_rawDesc = "" +
"\n" +
"\x18readers/v1/readers.proto\x12\n" +
"readers.v1\"\x8c\x04\n" +
"readers.v1\"\xac\x04\n" +
"\fPageMetadata\x12\x14\n" +
"\x05limit\x18\x01 \x01(\x04R\x05limit\x12\x16\n" +
"\x06offset\x18\x02 \x01(\x04R\x06offset\x12\x1a\n" +
@@ -747,7 +755,10 @@ const file_readers_v1_readers_proto_rawDesc = "" +
"comparator\x12\x16\n" +
"\x06format\x18\x11 \x01(\tR\x06format\x12\x14\n" +
"\x05order\x18\x12 \x01(\tR\x05order\x12\x10\n" +
"\x03dir\x18\x13 \x01(\tR\x03dir\"\x97\x01\n" +
"\x03dir\x18\x13 \x01(\tR\x03dir\x12\x1e\n" +
"\n" +
"publishers\x18\x14 \x03(\tR\n" +
"publishers\"\x97\x01\n" +
"\x0fReadMessagesRes\x12\x14\n" +
"\x05total\x18\x01 \x01(\x04R\x05total\x12=\n" +
"\rpage_metadata\x18\x02 \x01(\v2\x18.readers.v1.PageMetadataR\fpageMetadata\x12/\n" +
+1
View File
@@ -34,6 +34,7 @@ message PageMetadata {
string format = 17;
string order = 18;
string dir = 19;
repeated string publishers = 20;
}
message ReadMessagesRes {
+2
View File
@@ -63,6 +63,7 @@ func (client readersGrpcClient) ReadMessages(ctx context.Context, in *grpcReader
Interval: in.GetPageMetadata().GetInterval(),
Subtopic: in.GetPageMetadata().GetSubtopic(),
Publisher: in.GetPageMetadata().GetPublisher(),
Publishers: in.GetPageMetadata().GetPublishers(),
Protocol: in.GetPageMetadata().GetProtocol(),
Name: in.GetPageMetadata().GetName(),
Value: in.GetPageMetadata().GetValue(),
@@ -116,6 +117,7 @@ func encodeReadMessagesRequest(_ context.Context, grpcReq any) (any, error) {
Interval: req.pageMeta.Interval,
Subtopic: req.pageMeta.Subtopic,
Publisher: req.pageMeta.Publisher,
Publishers: req.pageMeta.Publishers,
Protocol: req.pageMeta.Protocol,
Name: req.pageMeta.Name,
Value: req.pageMeta.Value,
+1
View File
@@ -46,6 +46,7 @@ func decodeReadMessagesRequest(_ context.Context, grpcReq any) (any, error) {
Interval: req.GetPageMetadata().GetInterval(),
Subtopic: req.GetPageMetadata().GetSubtopic(),
Publisher: req.GetPageMetadata().GetPublisher(),
Publishers: req.GetPageMetadata().GetPublishers(),
Protocol: req.GetPageMetadata().GetProtocol(),
Name: req.GetPageMetadata().GetName(),
Value: req.GetPageMetadata().GetValue(),
+19 -18
View File
@@ -41,24 +41,25 @@ type MessagesPage struct {
// PageMetadata represents the parameters used to create database queries.
type PageMetadata struct {
Offset uint64 `json:"offset"`
Limit uint64 `json:"limit"`
Order string `json:"order,omitempty"`
Dir string `json:"dir,omitempty"`
Subtopic string `json:"subtopic,omitempty"`
Publisher string `json:"publisher,omitempty"`
Protocol string `json:"protocol,omitempty"`
Name string `json:"name,omitempty"`
Value float64 `json:"v,omitempty"`
Comparator string `json:"comparator,omitempty"`
BoolValue bool `json:"vb,omitempty"`
StringValue string `json:"vs,omitempty"`
DataValue string `json:"vd,omitempty"`
From float64 `json:"from,omitempty"`
To float64 `json:"to,omitempty"`
Format string `json:"format,omitempty"`
Aggregation string `json:"aggregation,omitempty"`
Interval string `json:"interval,omitempty"`
Offset uint64 `json:"offset"`
Limit uint64 `json:"limit"`
Order string `json:"order,omitempty"`
Dir string `json:"dir,omitempty"`
Subtopic string `json:"subtopic,omitempty"`
Publisher string `json:"publisher,omitempty"`
Publishers []string `json:"publishers,omitempty"`
Protocol string `json:"protocol,omitempty"`
Name string `json:"name,omitempty"`
Value float64 `json:"v,omitempty"`
Comparator string `json:"comparator,omitempty"`
BoolValue bool `json:"vb,omitempty"`
StringValue string `json:"vs,omitempty"`
DataValue string `json:"vd,omitempty"`
From float64 `json:"from,omitempty"`
To float64 `json:"to,omitempty"`
Format string `json:"format,omitempty"`
Aggregation string `json:"aggregation,omitempty"`
Interval string `json:"interval,omitempty"`
}
// ParseValueComparator convert comparison operator keys into mathematic anotation.
+30 -20
View File
@@ -18,12 +18,13 @@ import (
var _ readers.MessageRepository = (*postgresRepository)(nil)
const (
messageFieldChannel = "channel"
messageFieldName = "name"
messageFieldProtocol = "protocol"
messageFieldPublisher = "publisher"
messageFieldSubtopic = "subtopic"
messageFieldValue = "value"
messageFieldChannel = "channel"
messageFieldName = "name"
messageFieldProtocol = "protocol"
messageFieldPublisher = "publisher"
messageFieldPublishers = "publishers"
messageFieldSubtopic = "subtopic"
messageFieldValue = "value"
)
type postgresRepository struct {
@@ -52,19 +53,20 @@ func (tr postgresRepository) ReadAll(chanID string, rpm readers.PageMetadata) (r
LIMIT :limit OFFSET :offset;`, format, cond, order)
params := map[string]any{
messageFieldChannel: chanID,
"limit": rpm.Limit,
"offset": rpm.Offset,
messageFieldSubtopic: rpm.Subtopic,
messageFieldPublisher: rpm.Publisher,
messageFieldName: rpm.Name,
messageFieldProtocol: rpm.Protocol,
messageFieldValue: rpm.Value,
"bool_value": rpm.BoolValue,
"string_value": rpm.StringValue,
"data_value": rpm.DataValue,
"from": rpm.From,
"to": rpm.To,
messageFieldChannel: chanID,
"limit": rpm.Limit,
"offset": rpm.Offset,
messageFieldSubtopic: rpm.Subtopic,
messageFieldPublisher: rpm.Publisher,
messageFieldPublishers: rpm.Publishers,
messageFieldName: rpm.Name,
messageFieldProtocol: rpm.Protocol,
messageFieldValue: rpm.Value,
"bool_value": rpm.BoolValue,
"string_value": rpm.StringValue,
"data_value": rpm.DataValue,
"from": rpm.From,
"to": rpm.To,
}
rows, err := tr.db.NamedQuery(q, params)
if err != nil {
@@ -138,11 +140,19 @@ func fmtCondition(chanID string, rpm readers.PageMetadata) string {
return condition
}
_, hasPublishers := query[messageFieldPublishers]
for name := range query {
switch name {
case messageFieldPublisher:
if hasPublishers {
continue
}
condition = fmt.Sprintf(`%s AND %s = :%s`, condition, name, name)
case messageFieldPublishers:
condition = fmt.Sprintf(`%s AND %s = ANY(:%s)`, condition, messageFieldPublisher, messageFieldPublishers)
case
messageFieldSubtopic,
messageFieldPublisher,
messageFieldName,
messageFieldProtocol:
condition = fmt.Sprintf(`%s AND %s = :%s`, condition, name, name)
+24 -20
View File
@@ -27,12 +27,13 @@ const (
var _ readers.MessageRepository = (*timescaleRepository)(nil)
const (
messageFieldChannel = "channel"
messageFieldName = "name"
messageFieldProtocol = "protocol"
messageFieldPublisher = "publisher"
messageFieldSubtopic = "subtopic"
messageFieldValue = "value"
messageFieldChannel = "channel"
messageFieldName = "name"
messageFieldProtocol = "protocol"
messageFieldPublisher = "publisher"
messageFieldPublishers = "publishers"
messageFieldSubtopic = "subtopic"
messageFieldValue = "value"
)
type timescaleRepository struct {
@@ -112,19 +113,20 @@ func (tr timescaleRepository) ReadAll(chanID string, rpm readers.PageMetadata) (
}
params := map[string]any{
messageFieldChannel: chanID,
"limit": rpm.Limit,
"offset": rpm.Offset,
messageFieldSubtopic: rpm.Subtopic,
messageFieldPublisher: rpm.Publisher,
messageFieldName: rpm.Name,
messageFieldProtocol: rpm.Protocol,
messageFieldValue: rpm.Value,
"bool_value": rpm.BoolValue,
"string_value": rpm.StringValue,
"data_value": rpm.DataValue,
"from": rpm.From,
"to": rpm.To,
messageFieldChannel: chanID,
"limit": rpm.Limit,
"offset": rpm.Offset,
messageFieldSubtopic: rpm.Subtopic,
messageFieldPublisher: rpm.Publisher,
messageFieldPublishers: rpm.Publishers,
messageFieldName: rpm.Name,
messageFieldProtocol: rpm.Protocol,
messageFieldValue: rpm.Value,
"bool_value": rpm.BoolValue,
"string_value": rpm.StringValue,
"data_value": rpm.DataValue,
"from": rpm.From,
"to": rpm.To,
}
rows, err := tr.db.NamedQuery(q, params)
@@ -206,7 +208,9 @@ func fmtCondition(rpm readers.PageMetadata) string {
conditions = append(conditions, " subtopic = :subtopic ")
}
if _, ok := query[messageFieldPublisher]; ok {
if _, ok := query[messageFieldPublishers]; ok {
conditions = append(conditions, " publisher = ANY(:publishers) ")
} else if _, ok := query[messageFieldPublisher]; ok {
conditions = append(conditions, " publisher = :publisher ")
}