mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 18:36:30 +02:00
142 lines
3.5 KiB
Go
142 lines
3.5 KiB
Go
package databroker
|
|
|
|
import (
|
|
"google.golang.org/protobuf/encoding/protojson"
|
|
)
|
|
|
|
// RecordSetBundle is an index of databroker records by type
|
|
type RecordSetBundle map[string]RecordSet
|
|
|
|
// RecordSet is an index of databroker records by their id.
|
|
type RecordSet map[string]*Record
|
|
|
|
// RecordCompareFn is a function that compares two records.
|
|
type RecordCompareFn func(record1, record2 *Record) bool
|
|
|
|
// RecordTypes returns the types of records in the bundle.
|
|
func (rsb RecordSetBundle) RecordTypes() []string {
|
|
types := make([]string, 0, len(rsb))
|
|
for typ := range rsb {
|
|
types = append(types, typ)
|
|
}
|
|
return types
|
|
}
|
|
|
|
// Add adds a record to the bundle.
|
|
func (rsb RecordSetBundle) Add(record *Record) {
|
|
rs, ok := rsb[record.GetType()]
|
|
if !ok {
|
|
rs = make(RecordSet)
|
|
rsb[record.GetType()] = rs
|
|
}
|
|
rs[record.GetId()] = record
|
|
}
|
|
|
|
// GetAdded returns the records that are in other but not in rsb.
|
|
func (rsb RecordSetBundle) GetAdded(other RecordSetBundle) RecordSetBundle {
|
|
added := make(RecordSetBundle)
|
|
for otherType, otherRS := range other {
|
|
rs, ok := rsb[otherType]
|
|
if !ok {
|
|
added[otherType] = otherRS
|
|
continue
|
|
}
|
|
rss := rs.GetAdded(other[otherType])
|
|
if len(rss) > 0 {
|
|
added[otherType] = rss
|
|
}
|
|
}
|
|
return added
|
|
}
|
|
|
|
// GetRemoved returns the records that are in rs but not in other.
|
|
func (rsb RecordSetBundle) GetRemoved(other RecordSetBundle) RecordSetBundle {
|
|
return other.GetAdded(rsb)
|
|
}
|
|
|
|
// GetModified returns the records that are in both rs and other but have different data.
|
|
func (rsb RecordSetBundle) GetModified(other RecordSetBundle, cmpFn RecordCompareFn) RecordSetBundle {
|
|
modified := make(RecordSetBundle)
|
|
for otherType, otherRS := range other {
|
|
rs, ok := rsb[otherType]
|
|
if !ok {
|
|
continue
|
|
}
|
|
m := rs.GetModified(otherRS, cmpFn)
|
|
if len(m) > 0 {
|
|
modified[otherType] = m
|
|
}
|
|
}
|
|
return modified
|
|
}
|
|
|
|
// GetAdded returns the records that are in other but not in rs.
|
|
func (rs RecordSet) GetAdded(other RecordSet) RecordSet {
|
|
added := make(RecordSet)
|
|
for id, record := range other {
|
|
if _, ok := rs[id]; !ok {
|
|
added[id] = record
|
|
}
|
|
}
|
|
return added
|
|
}
|
|
|
|
// GetRemoved returns the records that are in rs but not in other.
|
|
func (rs RecordSet) GetRemoved(other RecordSet) RecordSet {
|
|
return other.GetAdded(rs)
|
|
}
|
|
|
|
// GetModified returns the records that are in both rs and other but have different data.
|
|
// by comparing the protobuf bytes of the payload.
|
|
func (rs RecordSet) GetModified(other RecordSet, cmpFn RecordCompareFn) RecordSet {
|
|
modified := make(RecordSet)
|
|
for id, record := range other {
|
|
otherRecord, ok := rs[id]
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
if !cmpFn(record, otherRecord) {
|
|
modified[id] = record
|
|
}
|
|
}
|
|
return modified
|
|
}
|
|
|
|
// Flatten returns all records in the set.
|
|
func (rs RecordSet) Flatten() []*Record {
|
|
records := make([]*Record, 0, len(rs))
|
|
for _, record := range rs {
|
|
records = append(records, record)
|
|
}
|
|
return records
|
|
}
|
|
|
|
// Flatten returns all records in the bundle.
|
|
func (rsb RecordSetBundle) Flatten() []*Record {
|
|
records := make([]*Record, 0)
|
|
for _, rs := range rsb {
|
|
records = append(records, rs.Flatten()...)
|
|
}
|
|
return records
|
|
}
|
|
|
|
// Get returns a record by type and id.
|
|
func (rsb RecordSetBundle) Get(typeName, id string) (record *Record, ok bool) {
|
|
rs, ok := rsb[typeName]
|
|
if !ok {
|
|
return
|
|
}
|
|
record, ok = rs[id]
|
|
return
|
|
}
|
|
|
|
// MarshalJSON marshals the record to JSON.
|
|
func (r *Record) MarshalJSON() ([]byte, error) {
|
|
return protojson.Marshal(r)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the record from JSON.
|
|
func (r *Record) UnmarshalJSON(data []byte) error {
|
|
return protojson.Unmarshal(data, r)
|
|
}
|