-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PA-24295 Inssqs Implementation (#17)
- Loading branch information
Showing
18 changed files
with
1,645 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package insdash | ||
|
||
import "encoding/json" | ||
|
||
func CreateBatches[T any](v []T, recordLimit int, byteLimit int) ([][]T, error) { | ||
batches := make([][]T, 0) | ||
buffer := make([]T, 0) | ||
bufferSize := 0 | ||
|
||
for _, record := range v { | ||
js, jsErr := json.Marshal(record) | ||
if jsErr != nil { | ||
return nil, jsErr | ||
} | ||
|
||
recordSize := len(js) | ||
sizeExceeds := bufferSize+recordSize > byteLimit | ||
bufferFull := len(buffer) == recordLimit | ||
|
||
if len(buffer) > 0 && (bufferFull || sizeExceeds) { | ||
batches = append(batches, buffer) | ||
buffer = make([]T, 0) | ||
bufferSize = 0 | ||
} | ||
|
||
buffer = append(buffer, record) | ||
bufferSize += recordSize | ||
} | ||
|
||
if len(buffer) > 0 { | ||
batches = append(batches, buffer) | ||
} | ||
|
||
return batches, nil | ||
} | ||
|
||
func Contains[T comparable](v []T, e T) bool { | ||
for _, a := range v { | ||
if a == e { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func MapToValueSlice[K comparable, V any](m map[K]V) []V { | ||
v := make([]V, 0, len(m)) | ||
for _, value := range m { | ||
v = append(v, value) | ||
} | ||
return v | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package insdash | ||
|
||
import ( | ||
"github.com/stretchr/testify/assert" | ||
"testing" | ||
) | ||
|
||
const kb64 = 64 * 1024 | ||
|
||
func Test_createBatches(t *testing.T) { | ||
t.Run("should_return_empty_batches_when_empty", func(t *testing.T) { | ||
batches, err := CreateBatches([]string{}, 10, kb64) | ||
|
||
assert.Nil(t, err, "err should be nil") | ||
assert.Equal(t, 0, len(batches), "batches length should be equal to 0") | ||
}) | ||
|
||
t.Run("should_return_batches_when_not_empty", func(t *testing.T) { | ||
batches, err := CreateBatches([]string{"test"}, 10, kb64) | ||
|
||
assert.Nil(t, err, "err should be nil") | ||
assert.Equal(t, 1, len(batches), "batches length should be equal to 1") | ||
}) | ||
|
||
t.Run("should_return_batches_by_record_limit", func(t *testing.T) { | ||
batches, err := CreateBatches([]string{"test", "test"}, 10, kb64) | ||
|
||
assert.Nil(t, err, "err should be nil") | ||
assert.Equal(t, 2, len(batches), "batches length should be equal to 2") | ||
}) | ||
|
||
t.Run("should_return_batches_by_byte_limit", func(t *testing.T) { | ||
batches, err := CreateBatches([]string{createString(kb64), createString(kb64)}, 10, kb64) | ||
|
||
assert.Nil(t, err, "err should be nil") | ||
assert.Equal(t, 2, len(batches), "batches length should be equal to 2") | ||
}) | ||
} | ||
|
||
func createString(byteSize int) string { | ||
var str string | ||
for i := 0; i < byteSize; i++ { | ||
str += "a" | ||
} | ||
return str | ||
} | ||
|
||
func TestMapToValueSlice(t *testing.T) { | ||
t.Run("should_return_empty_slice_when_empty", func(t *testing.T) { | ||
s := MapToValueSlice(map[string]string{}) | ||
assert.Equal(t, 0, len(s), "slice length should be equal to 0") | ||
assert.Equal(t, []string{}, s, "slice value should be equal to []string{}") | ||
}) | ||
|
||
t.Run("should_return_string_slice_when_not_empty", func(t *testing.T) { | ||
s := MapToValueSlice(map[string]string{"test": "test"}) | ||
assert.Equal(t, 1, len(s), "slice length should be equal to 1") | ||
assert.Equal(t, "test", s[0], "slice value should be equal to \"test\"") | ||
}) | ||
|
||
t.Run("should_return_int_slice_when_not_empty", func(t *testing.T) { | ||
s := MapToValueSlice(map[string]int{"test": 1}) | ||
assert.Equal(t, 1, len(s), "slice length should be equal to 1") | ||
assert.Equal(t, 1, s[0], "slice value should be equal to 1") | ||
}) | ||
|
||
t.Run("should_return_bool_slice_when_not_empty", func(t *testing.T) { | ||
s := MapToValueSlice(map[string]bool{"test": true}) | ||
assert.Equal(t, 1, len(s), "slice length should be equal to 1") | ||
assert.Equal(t, true, s[0], "slice value should be equal to true") | ||
}) | ||
|
||
t.Run("should_return_float_slice_when_not_empty", func(t *testing.T) { | ||
s := MapToValueSlice(map[string]float64{"test": 1.0}) | ||
assert.Equal(t, 1, len(s), "slice length should be equal to 1") | ||
assert.Equal(t, 1.0, s[0], "slice value should be equal to 1.0") | ||
}) | ||
|
||
t.Run("should_return_struct_slice_when_not_empty", func(t *testing.T) { | ||
s := MapToValueSlice(map[string]struct{}{"test": {}}) | ||
assert.Equal(t, 1, len(s), "slice length should be equal to 1") | ||
assert.Equal(t, struct{}{}, s[0], "slice value should be equal to struct{}{}") | ||
}) | ||
|
||
t.Run("should_return_interface_slice_when_not_empty", func(t *testing.T) { | ||
s := MapToValueSlice(map[string]interface{}{"test": 1}) | ||
assert.Equal(t, 1, len(s), "slice length should be equal to 1") | ||
assert.Equal(t, 1, s[0], "slice value should be equal to 1") | ||
}) | ||
|
||
t.Run("should_return_slice_when_not_empty", func(t *testing.T) { | ||
s := MapToValueSlice(map[string][]string{"test": {"test"}}) | ||
assert.Equal(t, 1, len(s), "slice length should be equal to 1") | ||
assert.Equal(t, []string{"test"}, s[0], "slice value should be equal to []string{\"test\"}") | ||
}) | ||
|
||
t.Run("should_return_map_slice_when_not_empty", func(t *testing.T) { | ||
s := MapToValueSlice(map[string]map[string]string{"test": {"test": "test"}}) | ||
assert.Equal(t, 1, len(s), "slice length should be equal to 1") | ||
assert.Equal(t, map[string]string{"test": "test"}, s[0], "slice value should be equal to map[string]string{\"test\": \"test\"}") | ||
}) | ||
|
||
t.Run("should_return_slice_with_multiple_values_when_not_empty", func(t *testing.T) { | ||
s := MapToValueSlice(map[string]string{"test": "test", "test2": "test2"}) | ||
assert.Equal(t, 2, len(s), "slice length should be equal to 2") | ||
assert.Equal(t, []string{"test", "test2"}, s, "slice value should be equal to []string{\"test\", \"test2\"}") | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# Inslogger | ||
|
||
Inslogger is a logging package designed to provide flexible and comprehensive logging capabilities in Go applications. | ||
|
||
## Features | ||
|
||
- **Multi-Level Logging:** Supports logging at various levels including Debug, Info, Warn, Error, and Fatal. | ||
- **Error Handling:** Provides methods to log errors with different formatting options. | ||
|
||
## Installation | ||
|
||
```bash | ||
go get github.com/yourusername/inslogger | ||
``` | ||
|
||
## Usage | ||
|
||
```go | ||
import "github.com/yourusername/inslogger" | ||
|
||
// Initialize a logger | ||
logger := inslogger.NewLogger(inslogger.Debug) | ||
|
||
// Log an error | ||
err := someFunction() | ||
if err != nil { | ||
logger.Error(err) | ||
} | ||
|
||
// Log a message | ||
logger.Log("This is a log message") | ||
|
||
// Set log level | ||
logger.SetLevel(inslogger.Info) | ||
``` | ||
|
||
## Interface | ||
The package provides an Interface that exposes various logging methods: | ||
```go | ||
type Interface interface { | ||
LogMultiple(errs []error) | ||
Log(i interface{}) | ||
Logf(format string, args ...interface{}) | ||
Warn(i interface{}) | ||
Warnf(format string, args ...interface{}) | ||
Error(err error) | ||
Errorf(format string, args ...interface{}) | ||
Debug(i interface{}) | ||
Debugf(format string, args ...interface{}) | ||
Fatal(err error) | ||
Fatalf(format string, args ...interface{}) | ||
initLogger() error | ||
SetLevel(level LogLevel) | ||
} | ||
``` | ||
|
||
|
||
# Configuration | ||
|
||
The `inslogger` package offers configuration options to customize logging behavior. | ||
|
||
## Log Levels | ||
|
||
The package supports the following log levels: | ||
|
||
- `DEBUG` | ||
- `INFO` | ||
- `WARN` | ||
- `ERROR` | ||
- `FATAL` | ||
|
||
## Setting Log Level | ||
|
||
The default log level is `INFO`. To set a different log level: | ||
|
||
```go | ||
logger := inslogger.NewLogger(inslogger.Debug) | ||
``` | ||
|
||
## Example | ||
```go | ||
// Initialize a logger with Debug level | ||
logger := inslogger.NewLogger(inslogger.Debug) | ||
|
||
// Log an error | ||
err := someFunction() | ||
if err != nil { | ||
logger.Error(err) | ||
} | ||
|
||
// Log a debug message | ||
logger.Debugf("Debug message with arguments: %s", arg) | ||
|
||
// Change log level to Info | ||
logger.SetLevel(inslogger.Info) | ||
|
||
// Log an informational message | ||
logger.Infof("Informational message") | ||
|
||
``` | ||
## Contribution | ||
Feel free to contribute by forking this repository and creating pull requests. Please ensure to adhere to the existing code style and conventions. | ||
|
Oops, something went wrong.