Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sqlstore): add sqlstore package #6835

Merged
merged 14 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ require (
github.com/soheilhy/cmux v0.1.5
github.com/srikanthccv/ClickHouse-go-mock v0.9.0
github.com/stretchr/testify v1.9.0
github.com/uptrace/bun v1.2.8
github.com/uptrace/bun/dialect/sqlitedialect v1.2.8
go.opentelemetry.io/collector/confmap v1.17.0
go.opentelemetry.io/collector/pdata v1.17.0
go.opentelemetry.io/collector/processor v0.111.0
Expand Down Expand Up @@ -120,6 +122,7 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jonboulle/clockwork v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
Expand Down Expand Up @@ -151,6 +154,7 @@ require (
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common/sigv4 v0.1.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/segmentio/backo-go v1.0.1 // indirect
Expand All @@ -162,8 +166,11 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
github.com/valyala/fastjson v1.6.4 // indirect
github.com/vjeantet/grok v1.0.1 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opencensus.io v0.24.0 // indirect
Expand Down Expand Up @@ -212,7 +219,7 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.30.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/time v0.6.0 // indirect
gonum.org/v1/gonum v0.15.1 // indirect
google.golang.org/api v0.199.0 // indirect
Expand Down
18 changes: 16 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/ionos-cloud/sdk-go/v6 v6.2.1 h1:mxxN+frNVmbFrmmFfXnBC3g2USYJrl6mc1LW2iNYbFY=
github.com/ionos-cloud/sdk-go/v6 v6.2.1/go.mod h1:SXrO9OGyWjd2rZhAhEpdYN6VUAODzzqRdqA9BCviQtI=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
Expand Down Expand Up @@ -661,6 +663,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4=
github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
Expand Down Expand Up @@ -740,12 +744,22 @@ github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
github.com/uptrace/bun v1.2.8 h1:HEiLvy9wc7ehU5S02+O6NdV5BLz48lL4REPhTkMX3Dg=
github.com/uptrace/bun v1.2.8/go.mod h1:JBq0uBKsKqNT0Ccce1IAFZY337Wkf08c6F6qlmfOHE8=
github.com/uptrace/bun/dialect/sqlitedialect v1.2.8 h1:Huqw7YhLFTbocbSv8NETYYXqKtwLa6XsciCWtjzWSWU=
github.com/uptrace/bun/dialect/sqlitedialect v1.2.8/go.mod h1:ni7h2uwIc5zPhxgmCMTEbefONc4XsVr/ATfz1Q7d3CE=
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
github.com/vjeantet/grok v1.0.1 h1:2rhIR7J4gThTgcZ1m2JY4TrJZNgjn985U28kT2wQrJ4=
github.com/vjeantet/grok v1.0.1/go.mod h1:ax1aAchzC6/QMXMcyzHQGZWaW1l195+uMYIkCWPCNIo=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs=
github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
Expand Down Expand Up @@ -1086,8 +1100,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
Expand Down
5 changes: 2 additions & 3 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import (
// This map contains the default values of all config structs
var (
defaults = map[string]signozconfmap.Config{
"instrumentation": &instrumentation.Config{},
"web": &web.Config{},
"cache": &cache.Config{},
"web": &web.Config{},
"cache": &cache.Config{},
}
)

Expand Down
37 changes: 37 additions & 0 deletions pkg/factory/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package factory

// Config is an interface that defines methods for creating and validating configurations.
type Config interface {
// Validate the configuration and returns an error if invalid.
Validate() error
}

// NewConfigFunc is a function that creates a new config.
type NewConfigFunc func() Config

// ConfigFactory is a factory that creates a new config.
type ConfigFactory interface {
Named
New() Config
}

// configFactory is a factory that implements the ConfigFactory interface.
type configFactory struct {
name Name
newConfigFunc NewConfigFunc
}

// Name returns the name of the factory.
func (factory *configFactory) Name() Name {
return factory.name
}

// New creates a new config.
func (factory *configFactory) New() Config {
return factory.newConfigFunc()
}

// Creates a new config factory.
func NewConfigFactory(name Name, f NewConfigFunc) ConfigFactory {
return &configFactory{name: name, newConfigFunc: f}
}
29 changes: 29 additions & 0 deletions pkg/factory/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package factory

import (
"testing"

"github.com/stretchr/testify/assert"
)

type c1 struct{}

func (c1) Validate() error {
return nil
}

func TestNewConfigFactory(t *testing.T) {
cf := NewConfigFactory(MustNewName("c1"), func() Config {
return c1{}
})
assert.Equal(t, MustNewName("c1"), cf.Name())
assert.IsType(t, c1{}, cf.New())
}

func TestNewConfigFactoryWithPointer(t *testing.T) {
cfp := NewConfigFactory(MustNewName("c1"), func() Config {
return &c1{}
})
assert.Equal(t, MustNewName("c1"), cfp.Name())
assert.IsType(t, &c1{}, cfp.New())
}
38 changes: 38 additions & 0 deletions pkg/factory/name.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package factory

import (
"fmt"
"regexp"
)

var (
// nameRegex is a regex that matches a valid name.
// It must start with a alphabet, and can only contain alphabets, numbers, underscores or hyphens.
nameRegex = regexp.MustCompile(`^[a-z][a-z0-9_-]{0,30}$`)
)

type Name struct {
name string
}

func (n Name) String() string {
return n.name
}

// NewName creates a new name.
func NewName(name string) (Name, error) {
if !nameRegex.MatchString(name) {
return Name{}, fmt.Errorf("invalid factory name %q", name)
}
return Name{name: name}, nil
}

// MustNewName creates a new name.
// It panics if the name is invalid.
func MustNewName(name string) Name {
n, err := NewName(name)
if err != nil {
panic(err)
}
return n
}
20 changes: 20 additions & 0 deletions pkg/factory/name_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package factory

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestName(t *testing.T) {
assert.Equal(t, Name{name: "c1"}, MustNewName("c1"))
}

func TestNameWithInvalidCharacters(t *testing.T) {
_, err := NewName("c1%")
assert.Error(t, err)

assert.Panics(t, func() {
MustNewName("c1%")
})
}
74 changes: 74 additions & 0 deletions pkg/factory/named.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package factory

import "fmt"

// Named is implemented by all types of factories.
type Named interface {
Name() Name
}

type NamedMap[T Named] struct {
factories map[Name]T
factoriesInOrder []T
}

// NewNamedMap creates a new NamedMap from a list of factories.
// It returns an error if the factories have duplicate names.
func NewNamedMap[T Named](factories ...T) (NamedMap[T], error) {
fmap := make(map[Name]T)
for _, factory := range factories {
if _, ok := fmap[factory.Name()]; ok {
return NamedMap[T]{}, fmt.Errorf("cannot build factory map, duplicate name %q found", factory.Name())
}

fmap[factory.Name()] = factory
}

return NamedMap[T]{factories: fmap, factoriesInOrder: factories}, nil
}

// MustNewNamedMap creates a new NamedMap from a list of factories.
// It panics if the factories have duplicate names.
func MustNewNamedMap[T Named](factories ...T) NamedMap[T] {
nm, err := NewNamedMap(factories...)
if err != nil {
panic(err)
}
return nm
}

// Get returns the factory for the given name by string.
// It returns an error if the factory is not found or the name is invalid.
func (n *NamedMap[T]) Get(namestr string) (t T, err error) {
name, err := NewName(namestr)
if err != nil {
return
}

factory, ok := n.factories[name]
if !ok {
err = fmt.Errorf("factory %q not found or not registered", name)
return
}

t = factory
return
}

// Add adds a factory to the NamedMap.
// It returns an error if the factory already exists.
func (n *NamedMap[T]) Add(factory T) (err error) {
name := factory.Name()
if _, ok := n.factories[name]; ok {
return fmt.Errorf("factory %q already exists", name)
}

n.factories[name] = factory
n.factoriesInOrder = append(n.factoriesInOrder, factory)
return nil
}

// GetInOrder returns the factories in the order they were added.
func (n *NamedMap[T]) GetInOrder() []T {
return n.factoriesInOrder
}
72 changes: 72 additions & 0 deletions pkg/factory/named_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package factory

import (
"testing"

"github.com/stretchr/testify/assert"
)

type f1 struct{}

func (*f1) Name() Name {
return MustNewName("f1")
}

type f2 struct{}

func (*f2) Name() Name {
return MustNewName("f2")
}

func TestNewNamedMap(t *testing.T) {
nm, err := NewNamedMap[Named](&f1{}, &f2{})
assert.NoError(t, err)
assert.Equal(t, map[Name]Named{
MustNewName("f1"): &f1{},
MustNewName("f2"): &f2{},
}, nm.factories)
assert.Equal(t, []Named{&f1{}, &f2{}}, nm.GetInOrder())
}

func TestNewNamedMapWithDuplicateNames(t *testing.T) {
_, err := NewNamedMap[Named](&f1{}, &f1{})
assert.Error(t, err)
}

func TestMustNewNamedMap(t *testing.T) {
nm := MustNewNamedMap[Named](&f1{}, &f2{})
assert.Equal(t, map[Name]Named{
MustNewName("f1"): &f1{},
MustNewName("f2"): &f2{},
}, nm.factories)
assert.Equal(t, []Named{&f1{}, &f2{}}, nm.GetInOrder())
}

func TestMustNewNamedMapDuplicateNames(t *testing.T) {
assert.Panics(t, func() {
MustNewNamedMap[Named](&f1{}, &f1{})
})
}

func TestNamedMapGet(t *testing.T) {
nm := MustNewNamedMap[Named](&f1{}, &f2{})

nf1, err := nm.Get("f1")
assert.NoError(t, err)
assert.IsType(t, &f1{}, nf1)

_, err = nm.Get("f3")
assert.Error(t, err)
}

func TestNamedMapAdd(t *testing.T) {
nm := MustNewNamedMap[Named](&f1{})

err := nm.Add(&f2{})
assert.NoError(t, err)
assert.Equal(t, map[Name]Named{
MustNewName("f1"): &f1{},
MustNewName("f2"): &f2{},
}, nm.factories)
assert.Equal(t, []Named{&f1{}, &f2{}}, nm.GetInOrder())
}
Loading
Loading