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

Library split #654

Closed
wants to merge 33 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4848c7b
Move `config` to `internal/config`
lippserd Oct 5, 2023
1f87f9e
Move `icingadb/objectpacker` to `objectpacker`
lippserd Oct 5, 2023
10ce1f0
Move `internal#CantPerformQuery()` to `database#CantPerformQuery()`
lippserd Oct 5, 2023
62fa5d5
Move database related contracts to `database/contracts`
lippserd Oct 5, 2023
96ff875
Introduce `strcase` for converting string cases
lippserd Oct 5, 2023
baf0e11
Move `utils#TableName()` to `database#TableName()`
lippserd Oct 5, 2023
09dfc22
`types#Binary`: Assert `fmt.Stringer` interface compliance
lippserd Oct 6, 2023
fabcd93
Move `utils#Name()` to `types#Name()`
lippserd Oct 6, 2023
38f5ce6
Move type related utility functions from `internal` to `types`
lippserd Oct 6, 2023
40fb51d
Use `google/go-cmp` to determine equality of checksums
lippserd Oct 6, 2023
574f9e5
Introduce `driver#Option`
lippserd Oct 6, 2023
2c4218c
Move `database#DB.CheckSchema()` to `icingadb#CheckSchema()`
lippserd Oct 6, 2023
6054c65
Move `com#SplitOnDupId()` to `database#SplitOnDupId()`
lippserd Oct 6, 2023
8a78df4
Move `contracts#Waiter{,Func}` to `com#Waiter{,Func}`
lippserd Oct 6, 2023
0873fb7
Make `com#CopyFirst()` generic
lippserd Oct 6, 2023
cdbee83
Add `context` to `com#WaitAsync()`
lippserd Oct 6, 2023
e63095e
Add `context` to `com#ErrgroupReceive()`
lippserd Oct 6, 2023
e7a7eac
Move `icingadb#DB` to `database#DB`
lippserd Oct 6, 2023
8a3fc48
`icingadb-migrate`: Don't alias `types` import
lippserd Oct 6, 2023
ff1b310
Move special types to `icingadb/types`
lippserd Oct 6, 2023
d360bf1
Decouple `structify` from `contracts`
lippserd Oct 7, 2023
a3b1e94
Add `utils#IsUnixAddr()`
lippserd Oct 9, 2023
547fb66
Add `logging#Config`
lippserd Oct 9, 2023
f0a99b5
Move database related code from `internal` to `database`
lippserd Oct 9, 2023
7ef33ac
Move `TLS` config options to `config#TLS`
lippserd Oct 9, 2023
9f0693e
Move `internal/config#ParseFlags()` to `config#ParseFlags()`
lippserd Oct 9, 2023
d7f6da7
Move `internal/config#FromYAMLFile()` to `config#FromYAMLFile()`
lippserd Oct 9, 2023
7425a41
Move `internal/config#Retention` to `internal/config#RetentionConfig`
lippserd Oct 9, 2023
582739f
Move Redis related code to `redis`
lippserd Oct 9, 2023
867cdf4
Don't set default port in `redis`
lippserd Oct 9, 2023
dddd055
Add `redis#Config.Database`
lippserd Oct 9, 2023
21f9f07
Use `icinga-go-library`
lippserd Nov 21, 2023
0b226ee
Remove library code
lippserd Nov 21, 2023
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
Prev Previous commit
Next Next commit
Move database related contracts to database/contracts
lippserd committed Nov 21, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 62fa5d57583cb03c69dc821aa97bacd6d44355ba
12 changes: 6 additions & 6 deletions cmd/icingadb-migrate/convert.go
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ package main
import (
"database/sql"
_ "embed"
"github.com/icinga/icingadb/pkg/contracts"
"github.com/icinga/icingadb/pkg/database"
v1 "github.com/icinga/icingadb/pkg/icingadb/v1"
"github.com/icinga/icingadb/pkg/icingadb/v1/history"
icingadbTypes "github.com/icinga/icingadb/pkg/types"
@@ -51,7 +51,7 @@ func convertCommentRows(
env string, envId icingadbTypes.Binary,
_ func(interface{}, string, ...interface{}), _ *sqlx.Tx, idoRows []commentRow,
) (stages []icingaDbOutputStage, checkpoint any) {
var commentHistory, acknowledgementHistory, allHistoryComment, allHistoryAck []contracts.Entity
var commentHistory, acknowledgementHistory, allHistoryComment, allHistoryAck []database.Entity

for _, row := range idoRows {
checkpoint = row.CommenthistoryId
@@ -247,7 +247,7 @@ func convertDowntimeRows(
env string, envId icingadbTypes.Binary,
_ func(interface{}, string, ...interface{}), _ *sqlx.Tx, idoRows []downtimeRow,
) (stages []icingaDbOutputStage, checkpoint any) {
var downtimeHistory, allHistory, sla []contracts.Entity
var downtimeHistory, allHistory, sla []database.Entity

for _, row := range idoRows {
checkpoint = row.DowntimehistoryId
@@ -416,7 +416,7 @@ func convertFlappingRows(
cachedById[c.HistoryId] = convertTime(c.EventTime, c.EventTimeUsec)
}

var flappingHistory, flappingHistoryUpserts, allHistory []contracts.Entity
var flappingHistory, flappingHistoryUpserts, allHistory []database.Entity
for _, row := range idoRows {
checkpoint = row.FlappinghistoryId

@@ -600,7 +600,7 @@ func convertNotificationRows(
perId[contact.Name1] = struct{}{}
}

var notificationHistory, userNotificationHistory, allHistory []contracts.Entity
var notificationHistory, userNotificationHistory, allHistory []database.Entity
for _, row := range idoRows {
checkpoint = row.NotificationId

@@ -773,7 +773,7 @@ func convertStateRows(
cachedById[c.HistoryId] = c.PreviousHardState
}

var stateHistory, allHistory, sla []contracts.Entity
var stateHistory, allHistory, sla []database.Entity
for _, row := range idoRows {
checkpoint = row.StatehistoryId

8 changes: 4 additions & 4 deletions cmd/icingadb-migrate/misc.go
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ package main
import (
"context"
"crypto/sha1"
"github.com/icinga/icingadb/pkg/contracts"
"github.com/icinga/icingadb/pkg/database"
"github.com/icinga/icingadb/pkg/driver"
"github.com/icinga/icingadb/pkg/icingadb"
"github.com/icinga/icingadb/pkg/objectpacker"
@@ -37,8 +37,8 @@ type IdoMigrationProgress struct {

// Assert interface compliance.
var (
_ contracts.Upserter = (*IdoMigrationProgressUpserter)(nil)
_ contracts.Upserter = (*IdoMigrationProgress)(nil)
_ database.Upserter = (*IdoMigrationProgressUpserter)(nil)
_ database.Upserter = (*IdoMigrationProgress)(nil)
)

// log is the root logger.
@@ -238,7 +238,7 @@ func (hts historyTypes) forEach(f func(*historyType)) {
}

type icingaDbOutputStage struct {
insert, upsert []contracts.Entity
insert, upsert []database.Entity
}

var types = historyTypes{
8 changes: 4 additions & 4 deletions pkg/com/bulker.go
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ package com

import (
"context"
"github.com/icinga/icingadb/pkg/contracts"
"github.com/icinga/icingadb/pkg/database"
"golang.org/x/sync/errgroup"
"sync"
"time"
@@ -23,7 +23,7 @@ func NeverSplit[T any]() BulkChunkSplitPolicy[T] {

// SplitOnDupId returns a state machine which tracks the inputs' IDs.
// Once an already seen input arrives, it demands splitting.
func SplitOnDupId[T contracts.IDer]() BulkChunkSplitPolicy[T] {
func SplitOnDupId[T database.IDer]() BulkChunkSplitPolicy[T] {
seenIds := map[string]struct{}{}

return func(ider T) bool {
@@ -182,6 +182,6 @@ func oneBulk[T any](ctx context.Context, ch <-chan T) <-chan []T {
}

var (
_ BulkChunkSplitPolicyFactory[struct{}] = NeverSplit[struct{}]
_ BulkChunkSplitPolicyFactory[contracts.Entity] = SplitOnDupId[contracts.Entity]
_ BulkChunkSplitPolicyFactory[struct{}] = NeverSplit[struct{}]
_ BulkChunkSplitPolicyFactory[database.Entity] = SplitOnDupId[database.Entity]
)
7 changes: 4 additions & 3 deletions pkg/com/com.go
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ package com
import (
"context"
"github.com/icinga/icingadb/pkg/contracts"
"github.com/icinga/icingadb/pkg/database"
"golang.org/x/sync/errgroup"
)

@@ -38,8 +39,8 @@ func ErrgroupReceive(g *errgroup.Group, err <-chan error) {

// CopyFirst asynchronously forwards all items from input to forward and synchronously returns the first item.
func CopyFirst(
ctx context.Context, input <-chan contracts.Entity,
) (first contracts.Entity, forward <-chan contracts.Entity, err error) {
ctx context.Context, input <-chan database.Entity,
) (first database.Entity, forward <-chan database.Entity, err error) {
var ok bool
select {
case <-ctx.Done():
@@ -52,7 +53,7 @@ func CopyFirst(
}

// Buffer of one because we receive an entity and send it back immediately.
fwd := make(chan contracts.Entity, 1)
fwd := make(chan database.Entity, 1)
fwd <- first

forward = fwd
17 changes: 9 additions & 8 deletions pkg/common/sync_subject.go
Original file line number Diff line number Diff line change
@@ -2,24 +2,25 @@ package common

import (
"github.com/icinga/icingadb/pkg/contracts"
"github.com/icinga/icingadb/pkg/database"
v1 "github.com/icinga/icingadb/pkg/icingadb/v1"
"github.com/icinga/icingadb/pkg/utils"
)

// SyncSubject defines information about entities to be synchronized.
type SyncSubject struct {
entity contracts.Entity
factory contracts.EntityFactoryFunc
entity database.Entity
factory database.EntityFactoryFunc
withChecksum bool
}

// NewSyncSubject returns a new SyncSubject.
func NewSyncSubject(factoryFunc contracts.EntityFactoryFunc) *SyncSubject {
func NewSyncSubject(factoryFunc database.EntityFactoryFunc) *SyncSubject {
e := factoryFunc()

var factory contracts.EntityFactoryFunc
var factory database.EntityFactoryFunc
if _, ok := e.(contracts.Initer); ok {
factory = func() contracts.Entity {
factory = func() database.Entity {
e := factoryFunc()
e.(contracts.Initer).Init()

@@ -39,20 +40,20 @@ func NewSyncSubject(factoryFunc contracts.EntityFactoryFunc) *SyncSubject {
}

// Entity returns one value from the factory. Always returns the same entity.
func (s SyncSubject) Entity() contracts.Entity {
func (s SyncSubject) Entity() database.Entity {
return s.entity
}

// Factory returns the entity factory function that calls Init() on the created contracts.Entity if applicable.
func (s SyncSubject) Factory() contracts.EntityFactoryFunc {
func (s SyncSubject) Factory() database.EntityFactoryFunc {
return s.factory
}

// FactoryForDelta behaves like Factory() unless s is WithChecksum().
// In the latter case it returns a factory for EntityWithChecksum instead.
// Rationale: Sync#ApplyDelta() uses its input entities which are WithChecksum() only for the delta itself
// and not for insertion into the database, so EntityWithChecksum is enough. And it consumes less memory.
func (s SyncSubject) FactoryForDelta() contracts.EntityFactoryFunc {
func (s SyncSubject) FactoryForDelta() database.EntityFactoryFunc {
if s.withChecksum {
return v1.NewEntityWithChecksum
}
48 changes: 0 additions & 48 deletions pkg/contracts/contracts.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,5 @@
package contracts

// Entity is implemented by every type Icinga DB should synchronize.
type Entity interface {
Fingerprinter
IDer
}

// Fingerprinter is implemented by every entity that uniquely identifies itself.
type Fingerprinter interface {
// Fingerprint returns the value that uniquely identifies the entity.
Fingerprint() Fingerprinter
}

// ID is a unique identifier of an entity.
type ID interface {
// String returns the string representation form of the ID.
// The String method is used to use the ID in functions
// where it needs to be compared or hashed.
String() string
}

// IDer is implemented by every entity that uniquely identifies itself.
type IDer interface {
ID() ID // ID returns the ID.
SetID(ID) // SetID sets the ID.
}

// Equaler is implemented by every type that is comparable.
type Equaler interface {
Equal(Equaler) bool // Equal checks for equality.
@@ -46,9 +20,6 @@ type Checksumer interface {
SetChecksum(Checksum) // SetChecksum sets the Checksum.
}

// EntityFactoryFunc knows how to create an Entity.
type EntityFactoryFunc func() Entity

// Waiter implements the Wait method,
// which blocks until execution is complete.
type Waiter interface {
@@ -69,22 +40,3 @@ func (f WaiterFunc) Wait() error {
type Initer interface {
Init() // Init initializes the object.
}

// Upserter implements the Upsert method,
// which returns a part of the object for ON DUPLICATE KEY UPDATE.
type Upserter interface {
Upsert() interface{} // Upsert partitions the object.
}

// TableNamer implements the TableName method,
// which returns the table of the object.
type TableNamer interface {
TableName() string // TableName tells the table.
}

// Scoper implements the Scope method,
// which returns a struct specifying the WHERE conditions that
// entities must satisfy in order to be SELECTed.
type Scoper interface {
Scope() interface{}
}
49 changes: 49 additions & 0 deletions pkg/database/contracts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package database

// ID is a unique identifier of an entity.
type ID interface {
// String returns the string representation form of the ID.
// The String method is used to use the ID in functions
// where it needs to be compared or hashed.
String() string
}

// IDer is implemented by every entity that uniquely identifies itself.
type IDer interface {
ID() ID // ID returns the ID.
SetID(ID) // SetID sets the ID.
}

// Fingerprinter is implemented by every entity that uniquely identifies itself.
type Fingerprinter interface {
// Fingerprint returns the value that uniquely identifies the entity.
Fingerprint() Fingerprinter
}

// Entity is implemented by each type that works with the database package.
type Entity interface {
Fingerprinter
IDer
}

// EntityFactoryFunc knows how to create an Entity.
type EntityFactoryFunc func() Entity

// Upserter implements the Upsert method,
// which returns a part of the object for ON DUPLICATE KEY UPDATE.
type Upserter interface {
Upsert() any // Upsert partitions the object.
}

// TableNamer implements the TableName method,
// which returns the table of the object.
type TableNamer interface {
TableName() string // TableName tells the table.
}

// Scoper implements the Scope method,
// which returns a struct specifying the WHERE conditions that
// entities must satisfy in order to be SELECTed.
type Scoper interface {
Scope() any
}
Loading