diff --git a/.test/event.json b/.test/event.json index 755b2c7..e01785e 100644 --- a/.test/event.json +++ b/.test/event.json @@ -5,7 +5,7 @@ "singular": "event", "plural": "events", "idPrefix": "e", - "indexSpecs": [], + "indexSpecs": [], "timeseries": { "timeField": "createdAt", "metaField": "name", diff --git a/main.go b/main.go index e6f5f16..c095922 100644 --- a/main.go +++ b/main.go @@ -51,6 +51,7 @@ type Timeseries struct { TimeField string `bson:"timeField"` MetaField string `bson:"metaField"` Granularity string `bson:"granularity"` + BucketMaxSpan int64 `bson:"bucketMaxSpan"` } type Discriminator struct { @@ -68,6 +69,7 @@ type CollectionDefinition struct { IndexSpecs []map[string]any `bson:"indexSpecs"` Schema map[string]any `bson:"schema"` Views map[string]any `bson:"views"` + Ttl int64 `bson:"ttl"` Timeseries *Timeseries `bson:"timeseries,omitempty"` Discriminator *Discriminator } @@ -86,6 +88,8 @@ type MongoClient struct { DBPrefix string // Registry holds critical information about collection's structure, like schema and indexes Registry map[string]*CollectionDefinition + // Alias collection names that map to a registered collection + Aliases map[string]string // Relaxed if set to true will not enforce schema Relaxed bool // Context fields to serialize when needed @@ -100,6 +104,18 @@ type MongoClient struct { IgnoreAudit []string } +// AddAlias will add the alias only if it doesn't exist. +func (c *MongoClient) AddAlias(alias, name string) { + if c.Aliases == nil { + c.Aliases = make(map[string]string) + } + _, ok := c.Aliases[alias] + if !ok { + log.Printf("Registering alias %s to %s", alias, name) + c.Aliases[alias] = name + } +} + func (c *MongoClient) SetRelaxed() { c.Relaxed = true } @@ -142,8 +158,7 @@ func (c *MongoClient) AddDefinition(data map[string]any) { if cd.Views != nil { for k, _ := range cd.Views { - log.Printf("Registering alias %s to %s", k, cd.Name) - c.Registry[k] = &cd + c.AddAlias(k, cd.Name) } } } @@ -231,7 +246,13 @@ func ApplyTimeSeries(cdef *CollectionDefinition, opts *options.CreateCollectionO SetMetaField(cdef.Timeseries.MetaField). SetGranularity(cdef.Timeseries.Granularity) + if cdef.Timeseries.BucketMaxSpan > 0 { + tsOpts.SetBucketMaxSpan(time.Duration(cdef.Timeseries.BucketMaxSpan) * time.Second) + } + opts.SetTimeSeriesOptions(tsOpts) + + opts.SetExpireAfterSeconds(cdef.Ttl) } else { log.Printf("No timeseries") } @@ -480,6 +501,10 @@ const ADD_DEFINITION_SCHEMA = ` "views": { "type": "object" }, + "ttl": { + "type": "integer", + "format": "int64" + }, "timeseries": { "type": "object", "properties": { @@ -491,6 +516,10 @@ const ADD_DEFINITION_SCHEMA = ` }, "granularity": { "enum": [ "seconds", "minutes", "hours"] + }, + "bucketMaxSpan": { + "type": "integer", + "format": "int64" } }, "required": ["timeField", "metaField", "granularity"]