db

package
v0.0.0-...-bb2f907 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2023 License: Apache-2.0 Imports: 27 Imported by: 35

README

SPDX-License-Identifier: Apache-2.0

Database Abstraction Layer

This package contains implementations of the Database interface defined in store.go Any database can be used as the backend as long as the following interface is implemented;

type Store interface {
	// Returns nil if db health is good
	HealthCheck() error

	// Unmarshal implements any unmarshalling needed for the database
	Unmarshal(inp []byte, out interface{}) error

	// Inserts and Updates a tag with key and also adds query fields if provided
	Insert(coll string, key Key, query interface{}, tag string, data interface{}) error

	// Find the document(s) with key and get the tag values from the document(s)
	Find(coll string, key Key, tag string) ([][]byte, error)

	// Removes the document(s) matching the key
	Remove(coll string, key Key) error
}

With this interface multiple database types can be supported by providing backends.

Details on Mongo Implementation

mongo.go implements the above interface using the go.mongodb.org/mongo-driver package. The code converts incoming binary data and creates a new document in the database.

Insert

Arguments:

collection string
key interface
query interface
tag string
data []byte

Insert function inserts the provided data into the collection as a document in MongoDB. FindOneAndUpdate mongo API is used to achieve this with the upsert option set to true. With this if the record doesn't exist it is created and if it exists it is updated with new data for the tag.

Key and Query parameters are assumed to be json structures with each element as part of the key. Those key-value pairs are used as the key for the document. Internally this API takes all the fields in the Key structure and adds them as fields in the document. Query parameter works just like key and it is used to add additional fields to the document.

With this key the document can be quried with Mongo Find function for both the key fields and Query fields.

This API also adds another field called "keyId" field to the document. The "keyId" field is concatenation of the key part of the Key parameter. Internally this is used to figure out the type of the document.

Assumption is that all the elememts of the key structure are strings.

Example of Key Structure
type CompositeAppKey struct {
	CompositeAppName string `json:"compositeApp"`
	Version          string `json:"compositeAppVersion"`
	Project          string `json:"project"`
}
Example of Key Values
key := CompositeAppKey{
		CompositeAppName:  "ca1",
		Version:           "v1",
		Project:           "testProject",
	}
Example of Query Structure
type Query struct {
	Userdata1 string `json:"userdata1"`
}
Example of Document store in MongoDB
{
   "_id":"ObjectId("   "5e54c206f53ca130893c8020"   ")",
   "compositeApp":"ca1",
   "project":"testProject",
   "compositeAppVersion":"v1",
   "compositeAppmetadata":{
      "metadata":{
         "name":"ca1",
         "description":"Test ca",
         "userdata1":"Data1",
         "userdata2":"Data2"
      },
      "spec":{
         "compositeAppVersion":"v1"
      }
   },
   "key":"{compositeApp,compositeAppVersion,project,}"
}
Find

Arguments:

collection string
key interface
tag string

Find function return one or more tag data based on the Key value. If key has all the fields defined then an exact match is looked for based on the key passed in. If some of the field value in structure are empty strings then this function returns all the documents which have the same type. (ANY operation)

Example of Exact Match based on fields Key Values
key := CompositeAppKey{
		CompositeAppName:  "ca1",
		Version:           "v1",
		Project:           "testProject",
	}
Example of Match based on some fields

This example will return all the compositeApp under project testProject.

key := CompositeAppKey{
		Project:           "testProject",
		CompositeAppName:  "",
		Version:           "",
		
	}

NOTE: Key structure can be different from the original key and can include Query fields also. ANY operation is not supported for Query fields.

RemoveAll

Arguments:

collection string
key interface

Similar to find. This will remove one or more documents based on the key structure.

Remove

Arguments:

collection string
key interface

This will remove one document based on the key structure. If child refrences exist for the key then the document will not be removed.

Unmarshal

Data in mongo is stored as bson which is a compressed form of json. We need mongo to convert the stored bson data to regular json that we can use in our code when returned.

bson.Unmarshal API is used to achieve this.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeSerialize

func DeSerialize(str string, v interface{}) error

DeSerialize converts string to a json object specified by type

func InitializeDatabaseConnection

func InitializeDatabaseConnection(ctx context.Context, dbName string) error

InitializeDatabaseConnection sets up the connection to the configured database to allow the application to talk to it.

func Serialize

func Serialize(v interface{}) (string, error)

Serialize converts given data into a JSON string

Types

type DbInfo

type DbInfo struct {
	StoreName string // name of the db collection to use for client documents
	TagMeta   string // attribute key name for the json data of a client document
	TagState  string // attribute key name for the resource state
}

DbInfo holds the DB collection and attributes info

type DbSchema

type DbSchema struct {
	Name      string           `json:"name"`
	Resources []ResourceSchema `json:"resources"`
	SegmentId string
}

DbSchema is the top level structure for the referential schema.

type DbSchemaKey

type DbSchemaKey struct {
	SegmentId string
}

func (DbSchemaKey) String

func (key DbSchemaKey) String() string

type Key

type Key interface {
}

Key is an interface that will be implemented by anypackage that wants to use the Store interface. This allows various db backends and key types.

type MockDB

type MockDB struct {
	Items      []map[string]map[string][]byte
	Err        error
	MarshalErr error
}

func (*MockDB) Find

func (m *MockDB) Find(ctx context.Context, table string, key Key, tag string) ([][]byte, error)

func (*MockDB) HealthCheck

func (m *MockDB) HealthCheck(ctx context.Context) error

func (*MockDB) Insert

func (m *MockDB) Insert(ctx context.Context, table string, key Key, query interface{}, tag string, data interface{}) error

func (*MockDB) Remove

func (m *MockDB) Remove(ctx context.Context, table string, key Key) error

func (*MockDB) RemoveAll

func (m *MockDB) RemoveAll(ctx context.Context, table string, key Key) error

func (*MockDB) RemoveTag

func (m *MockDB) RemoveTag(ctx context.Context, table string, key Key, tag string) error

func (*MockDB) Unmarshal

func (m *MockDB) Unmarshal(inp []byte, out interface{}) error

type MockMongoStore

type MockMongoStore struct {
	// contains filtered or unexported fields
}

func (*MockMongoStore) ReadRefSchema

func (m *MockMongoStore) ReadRefSchema(ctx context.Context) error

ReadRefSchema reads the Referential Schema Segment file and creates the refSchemaMap.

type MongoCollection

type MongoCollection interface {
	InsertOne(ctx context.Context, document interface{},
		opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error)
	FindOne(ctx context.Context, filter interface{},
		opts ...*options.FindOneOptions) *mongo.SingleResult
	FindOneAndUpdate(ctx context.Context, filter interface{},
		update interface{}, opts ...*options.FindOneAndUpdateOptions) *mongo.SingleResult
	DeleteOne(ctx context.Context, filter interface{},
		opts ...*options.DeleteOptions) (*mongo.DeleteResult, error)
	DeleteMany(ctx context.Context, filter interface{},
		opts ...*options.DeleteOptions) (*mongo.DeleteResult, error)
	Find(ctx context.Context, filter interface{},
		opts ...*options.FindOptions) (*mongo.Cursor, error)
	UpdateOne(ctx context.Context, filter interface{}, update interface{},
		opts ...*options.UpdateOptions) (*mongo.UpdateResult, error)
	CountDocuments(ctx context.Context, filter interface{},
		opts ...*options.CountOptions) (int64, error)
}

MongoCollection defines the a subset of MongoDB operations Note: This interface is defined mainly for mock testing

type MongoStore

type MongoStore struct {
	// contains filtered or unexported fields
}

MongoStore is an implementation of the db.Store interface

func (*MongoStore) Find

func (m *MongoStore) Find(ctx context.Context, coll string, key Key, tag string) ([][]byte, error)

Find method returns the data stored for this key and for this particular tag

func (*MongoStore) HealthCheck

func (m *MongoStore) HealthCheck(ctx context.Context) error

HealthCheck verifies if the database is up and running

func (*MongoStore) Insert

func (m *MongoStore) Insert(ctx context.Context, coll string, key Key, query interface{}, tag string, data interface{}) error

Insert is used to insert/add element to a document

func (*MongoStore) ReadRefSchema

func (m *MongoStore) ReadRefSchema(ctx context.Context)

ReadRefSchema reads the Referential Schema Segment file and creates the refSchemaMap.

func (*MongoStore) Remove

func (m *MongoStore) Remove(ctx context.Context, coll string, key Key) error

Remove method to remove the documet by key if no child references

func (*MongoStore) RemoveAll

func (m *MongoStore) RemoveAll(ctx context.Context, coll string, key Key) error

RemoveAll method to removes all the documet matching key

func (*MongoStore) RemoveTag

func (m *MongoStore) RemoveTag(ctx context.Context, coll string, key Key, tag string) error

RemoveTag is used to remove an element from a document

func (*MongoStore) Unmarshal

func (m *MongoStore) Unmarshal(inp []byte, out interface{}) error

Unmarshal implements an unmarshaler for bson data that is produced from the mongo database

type NewMockDB

type NewMockDB struct {
	Items      []map[string]map[string][]byte
	Err        error
	MarshalErr error
}

func (*NewMockDB) Find

func (m *NewMockDB) Find(ctx context.Context, table string, key Key, tag string) ([][]byte, error)

func (*NewMockDB) HealthCheck

func (m *NewMockDB) HealthCheck(ctx context.Context) error

func (*NewMockDB) Insert

func (m *NewMockDB) Insert(ctx context.Context, table string, key Key, query interface{}, tag string, data interface{}) error

func (*NewMockDB) Remove

func (m *NewMockDB) Remove(ctx context.Context, table string, key Key) error

func (*NewMockDB) RemoveAll

func (m *NewMockDB) RemoveAll(ctx context.Context, table string, key Key) error

func (*NewMockDB) RemoveTag

func (m *NewMockDB) RemoveTag(ctx context.Context, table string, key Key, tag string) error

func (*NewMockDB) Unmarshal

func (m *NewMockDB) Unmarshal(inp []byte, out interface{}) error

type ReferenceEntry

type ReferenceEntry struct {
	Key   Key
	KeyId string
}

type ReferenceSchema

type ReferenceSchema struct {
	Name       string            `yaml:"name"`
	Type       string            `yaml:"type"`       // can be not present or "map" or "many"
	CommonKey  string            `yaml:"commonKey"`  // optional to disambiguate - part of reference key that is common
	Map        string            `yaml:"map"`        // if Type is "map", this is JSON tag of the Map object
	FixedKv    map[string]string `yaml:"fixedKv"`    // Key/Values of referenced resource that are known at compile time
	FilterKeys []string          `yaml:"filterKeys"` // if "map" type, list of keys to filter (not count as references)
}

ReferenceSchema defines the structure of a reference entry in the referential schema.

type ReferentialSchema

type ReferentialSchema struct {
	// contains filtered or unexported fields
}

ReferentialSchema defines the structure that will be prepared for each element of the referential schema map.

type ResourceSchema

type ResourceSchema struct {
	Name       string            `yaml:"name"`
	Parent     string            `yaml:"parent"`
	References []ReferenceSchema `yaml:"references"` // if present, overrides default resource id
}

ResourceSchema defines the structure of a data resource in the referential schema.

type Store

type Store interface {
	// Returns nil if db health is good
	HealthCheck(ctx context.Context) error

	// Unmarshal implements any unmarshalling needed for the database
	Unmarshal(inp []byte, out interface{}) error

	// Inserts and Updates a tag with key and also adds query fields if provided
	Insert(ctx context.Context, coll string, key Key, query interface{}, tag string, data interface{}) error

	// Find the document(s) with key and get the tag values from the document(s)
	Find(ctx context.Context, coll string, key Key, tag string) ([][]byte, error)

	// Removes the document(s) matching the key if no child reference in collection
	Remove(ctx context.Context, coll string, key Key) error

	// Remove all the document(s) matching the key
	RemoveAll(ctx context.Context, coll string, key Key) error

	// Remove the specifiec tag from the document matching the key
	RemoveTag(ctx context.Context, coll string, key Key, tag string) error
}

Store is an interface for accessing the database

var DBconn Store

DBconn interface used to talk a concrete Database connection

func NewMongoStore

func NewMongoStore(ctx context.Context, name string, store *mongo.Database) (Store, error)

NewMongoStore initializes a Mongo Database with the name provided If a database with that name exists, it will be returned

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL