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

Query versioning support #1

Merged
merged 6 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 6 additions & 1 deletion .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,13 @@ jobs:
- name: Display Go version
run: go version

- name: Start MongoDB
uses: supercharge/[email protected]
with:
mongodb-version: '8.0'

- name: Run tests
run: go test
run: go test ./...

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,10 @@ jobs:
- name: Display Go version
run: go version

- name: Start MongoDB
uses: supercharge/[email protected]
with:
mongodb-version: '8.0'

- name: Run tests
run: go test
run: go test ./...
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Application written in Go to collect the information from webpages or API endpoi
## Prerequisites

- Tested with Go 1.23.2
- [MongoDB](https://www.mongodb.com/docs/manual/administration/install-community/)
- [MongoDB 8.0](https://www.mongodb.com/docs/manual/administration/install-community/)

## Installation

Expand Down
2 changes: 2 additions & 0 deletions autoini/autoini.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ func ReadIni[T Configurable](path string) (result T) {
setStringKey(result, fieldName, reflect.Indirect(configReflection).Field(i), cfg)
case "int":
setIntKey(result, fieldName, reflect.Indirect(configReflection).Field(i), cfg)
case "int64":
setIntKey(result, fieldName, reflect.Indirect(configReflection).Field(i), cfg)
case "bool":
setBoolKey(result, fieldName, reflect.Indirect(configReflection).Field(i), cfg)
default:
Expand Down
25 changes: 25 additions & 0 deletions hash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
"crypto/sha256"
"fmt"
"io"
"os"
)

func GetFileHash(path string) (hash string, err error) {
file, err := os.Open(path)
if err != nil {
return
}
defer file.Close()

var hashFunction = sha256.New()
_, err = io.Copy(hashFunction, file)
if err != nil {
return
}

hash = fmt.Sprintf("%x", hashFunction.Sum(nil))
return
}
26 changes: 26 additions & 0 deletions hash_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
"testing"

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

func TestGetFileHashValid(t *testing.T) {
var assert = assert.New(t)

var hash, err = GetFileHash("hash_test.go")
assert.Equal(nil, err, "Returned an error 1")
assert.Equal(64, len(hash), "Incorrect hash length 1")

hash, err = GetFileHash("test/example.txt")
assert.Equal(nil, err, "Returned an error 2")
assert.Equal("a9a66978f378456c818fb8a3e7c6ad3d2c83e62724ccbdea7b36253fb8df5edd", hash, "Incorrect hash length 2")
}

func TestGetFileHashInvalid(t *testing.T) {
var assert = assert.New(t)

var _, err = GetFileHash("invalid.exe")
assert.NotEqual(nil, err, "Did not return an error 1")
}
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ func main() {
defer mongo.Disconnect()

// Create the default versions collection
err = mongo.CreateCollection("versions")
err = mongo.CreateCollection(config.VersionCollectionName)
if err != nil {
log.Fatal(err)
}

var dir = "./queries"
var stopRequest = make(chan any)
var stopResponse = make(chan any)
err = StartTrackers(ListIniFiles(dir), mongo, stopRequest, stopResponse)
err = StartTrackers(ListIniFiles(dir), config, mongo, stopRequest, stopResponse)
if err != nil {
log.Fatal(err)
}
Expand Down
66 changes: 56 additions & 10 deletions mongodb/mongodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mongodb

import (
"context"
"errors"
"time"

"go.mongodb.org/mongo-driver/v2/bson"
Expand All @@ -10,6 +11,15 @@ import (
"go.mongodb.org/mongo-driver/v2/mongo/readpref"
)

func BsonToRaw(value bson.D) (document bson.Raw, err error) {
doc, err := bson.Marshal(value)
if err != nil {
return document, err
}
err = bson.Unmarshal(doc, &document)
return
}

type MongoDB struct {
client *mongo.Client
database *mongo.Database
Expand All @@ -34,24 +44,30 @@ func NewMongoDB(uri string, databaseName string) (result MongoDB, err error) {
return result, err
}

func Connect(uri string) (client *mongo.Client, err error) {
return mongo.Connect(options.Client().ApplyURI(uri))
}
func (m *MongoDB) Disconnect() error {
if m.client == nil {
return errors.New("client is nil")
}

func (m *MongoDB) Disconnect() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

if err := m.client.Disconnect(ctx); err != nil {
panic(err)
}

return nil
}

func (m *MongoDB) CreateCollection(collection string) (err error) {
if m.database == nil {
return errors.New("database is nil")
}

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
// Ensure that we create only missing collection
names, err := m.database.ListCollectionNames(ctx, bson.D{{"name", collection}})
// Ensure that we create only a missing collection
names, err := m.database.ListCollectionNames(ctx, bson.D{{Key: "name", Value: collection}})
if err != nil {
return err
}
Expand All @@ -64,6 +80,10 @@ func (m *MongoDB) CreateCollection(collection string) (err error) {
}

func (m *MongoDB) Write(collection string, data bson.D) (err error) {
if m.database == nil {
return errors.New("database is nil")
}

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
mongoCollection := m.database.Collection(collection)
Expand All @@ -72,26 +92,39 @@ func (m *MongoDB) Write(collection string, data bson.D) (err error) {
return err
}

func (m *MongoDB) GetLastDocument(collection string, sortedKey string) (result bson.D, err error) {
func (m *MongoDB) GetLastDocumentFiltered(collection string, sortedKey string, filter bson.D) (result bson.D, err error) {
if m.database == nil {
return result, errors.New("database is nil")
}

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

mongoCollection := m.database.Collection(collection)
count, err := mongoCollection.CountDocuments(ctx, bson.D{})
count, err := mongoCollection.CountDocuments(ctx, filter)
if err != nil || count == 0 {
return result, err
}
opts := options.FindOne().SetSort(bson.D{{sortedKey, 1}}).SetSkip(count - 1)
opts := options.FindOne().SetSort(bson.D{{Key: sortedKey, Value: 1}}).SetSkip(count - 1)

err = mongoCollection.FindOne(ctx, bson.D{}, opts).Decode(&result)
// TODO: Return un-decoded result
err = mongoCollection.FindOne(ctx, filter, opts).Decode(&result)
if err != nil {
return result, err
}

return
}

func (m *MongoDB) GetLastDocument(collection string, sortedKey string) (result bson.D, err error) {
return m.GetLastDocumentFiltered(collection, sortedKey, bson.D{})
}

func (m *MongoDB) GetAllDocuments(collection string) (result []bson.D, err error) {
if m.database == nil {
return result, errors.New("database is nil")
}

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

Expand All @@ -116,3 +149,16 @@ func (m *MongoDB) GetAllDocuments(collection string) (result []bson.D, err error

return
}

func (m *MongoDB) DropCollection(collection string) (err error) {
if m.database == nil {
return errors.New("database is nil")
}

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

mongoCollection := m.database.Collection(collection)
err = mongoCollection.Drop(ctx)
return
}
Loading