File: inmemory.go

package info (click to toggle)
golang-github-socketplane-libovsdb 0.8.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,468 kB
  • sloc: makefile: 59; sh: 27
file content (141 lines) | stat: -rw-r--r-- 3,822 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package inmemory

import (
	"fmt"
	"sync"

	"github.com/go-logr/logr"
	"github.com/google/uuid"
	"github.com/ovn-kubernetes/libovsdb/cache"
	dbase "github.com/ovn-kubernetes/libovsdb/database"
	"github.com/ovn-kubernetes/libovsdb/database/transaction"
	"github.com/ovn-kubernetes/libovsdb/model"
	"github.com/ovn-kubernetes/libovsdb/ovsdb"
)

type inMemoryDatabase struct {
	databases  map[string]*cache.TableCache
	models     map[string]model.ClientDBModel
	references map[string]dbase.References
	logger     *logr.Logger
	mutex      sync.RWMutex
}

func NewDatabase(models map[string]model.ClientDBModel, logger *logr.Logger) dbase.Database {
	return &inMemoryDatabase{
		databases:  make(map[string]*cache.TableCache),
		models:     models,
		references: make(map[string]dbase.References),
		mutex:      sync.RWMutex{},
		logger:     logger,
	}
}

func (db *inMemoryDatabase) NewTransaction(dbName string) dbase.Transaction {
	db.mutex.Lock()
	defer db.mutex.Unlock()
	var model model.DatabaseModel
	if database, ok := db.databases[dbName]; ok {
		model = database.DatabaseModel()
	}
	transaction := transaction.NewTransaction(model, dbName, db, db.logger)
	return &transaction
}

func (db *inMemoryDatabase) CreateDatabase(name string, schema ovsdb.DatabaseSchema) error {
	db.mutex.Lock()
	defer db.mutex.Unlock()
	var mo model.ClientDBModel
	var ok bool
	if mo, ok = db.models[schema.Name]; !ok {
		return fmt.Errorf("no db model provided for schema with name %s", name)
	}
	dbModel, errs := model.NewDatabaseModel(schema, mo)
	if len(errs) > 0 {
		return fmt.Errorf("failed to create DatabaseModel: %#+v", errs)
	}
	database, err := cache.NewTableCache(dbModel, nil, nil)
	if err != nil {
		return err
	}
	db.databases[name] = database
	db.references[name] = make(dbase.References)
	return nil
}

func (db *inMemoryDatabase) Exists(name string) bool {
	db.mutex.RLock()
	defer db.mutex.RUnlock()
	_, ok := db.databases[name]
	return ok
}

func (db *inMemoryDatabase) Commit(database string, _ uuid.UUID, update dbase.Update) error {
	if !db.Exists(database) {
		return fmt.Errorf("db does not exist")
	}
	db.mutex.RLock()
	targetDb := db.databases[database]
	db.mutex.RUnlock()

	err := targetDb.ApplyCacheUpdate(update)
	if err != nil {
		return err
	}

	return update.ForReferenceUpdates(func(references dbase.References) error {
		db.references[database].UpdateReferences(references)
		return nil
	})
}

func (db *inMemoryDatabase) CheckIndexes(database string, table string, m model.Model) error {
	if !db.Exists(database) {
		return nil
	}
	db.mutex.RLock()
	targetDb := db.databases[database]
	db.mutex.RUnlock()
	targetTable := targetDb.Table(table)
	return targetTable.IndexExists(m)
}

func (db *inMemoryDatabase) List(database, table string, conditions ...ovsdb.Condition) (map[string]model.Model, error) {
	if !db.Exists(database) {
		return nil, fmt.Errorf("db does not exist")
	}
	db.mutex.RLock()
	targetDb := db.databases[database]
	db.mutex.RUnlock()

	targetTable := targetDb.Table(table)
	if targetTable == nil {
		return nil, fmt.Errorf("table does not exist")
	}

	return targetTable.RowsByCondition(conditions)
}

func (db *inMemoryDatabase) Get(database, table string, uuid string) (model.Model, error) {
	if !db.Exists(database) {
		return nil, fmt.Errorf("db does not exist")
	}
	db.mutex.RLock()
	targetDb := db.databases[database]
	db.mutex.RUnlock()

	targetTable := targetDb.Table(table)
	if targetTable == nil {
		return nil, fmt.Errorf("table does not exist")
	}
	return targetTable.Row(uuid), nil
}

func (db *inMemoryDatabase) GetReferences(database, table, row string) (dbase.References, error) {
	if !db.Exists(database) {
		return nil, fmt.Errorf("db does not exist")
	}
	db.mutex.RLock()
	defer db.mutex.RUnlock()
	return db.references[database].GetReferences(table, row), nil
}