From b8d9ff4f72c3e265b9bb96c6d99f2cb82a48bd56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Caama=C3=B1o=20Ruiz?= Date: Wed, 1 Jun 2022 13:16:11 +0000 Subject: [PATCH] Support primary and secondary client indexes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduces two types of client indexes: primary and secondary. Primary indexes are verified to no be duplicate at transaction verification, when enable, otherwise there is no difference between them. Signed-off-by: Jaime CaamaƱo Ruiz --- cache/cache.go | 22 +++++++++++++++------- model/client.go | 14 ++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/cache/cache.go b/cache/cache.go index 284ff55e..ddc3f1ac 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -83,9 +83,14 @@ type indexType uint const ( schemaIndexType indexType = iota - clientIndexType + primaryClientIndexType + secondaryClientIndexType ) +func clientIndexTypeToCacheIndexType(modelIndexType model.IndexType) indexType { + return indexType(modelIndexType + 1) +} + // indexSpec contains details about an index type indexSpec struct { index index @@ -94,13 +99,17 @@ type indexSpec struct { } func (s indexSpec) isClientIndex() bool { - return s.indexType == clientIndexType + return s.indexType >= primaryClientIndexType } func (s indexSpec) isSchemaIndex() bool { return s.indexType == schemaIndexType } +func (s indexSpec) isPrimaryIndex() bool { + return s.indexType < secondaryClientIndexType +} + // newIndex builds a index from a list of columns func newIndexFromColumns(columns ...string) index { sort.Strings(columns) @@ -372,10 +381,8 @@ func (r *RowCache) IndexExists(row model.Model) error { } uuid := field.(string) for _, indexSpec := range r.indexSpecs { - if !indexSpec.isSchemaIndex() { - // Given the ordered indexSpecs, we can break here if we reach the - // first non schema index - break + if !indexSpec.isPrimaryIndex() { + continue } index := indexSpec.index val, err := valueFromIndex(info, indexSpec.columns) @@ -1103,7 +1110,8 @@ func newRowCache(name string, dbModel model.DatabaseModel, dataType reflect.Type if _, ok := indexes[index]; ok { continue } - spec := indexSpec{index: index, columns: columnKeys, indexType: clientIndexType} + indexType := clientIndexTypeToCacheIndexType(clientIndex.Type) + spec := indexSpec{index: index, columns: columnKeys, indexType: indexType} r.indexSpecs = append(r.indexSpecs, spec) indexes[index] = spec } diff --git a/model/client.go b/model/client.go index 5eb68624..220c2916 100644 --- a/model/client.go +++ b/model/client.go @@ -14,9 +14,22 @@ type ColumnKey struct { Key interface{} } +// IndexType is the type of client index +type IndexType uint + +const ( + // PrimaryIndexType are client indexes for which uniqueness is optionally + // enforced in the context of a specific client instance transaction before + // it is sent to the server. + PrimaryIndexType IndexType = iota + // SecondaryIndexType are indexes for which uniqueness is not enforced. + SecondaryIndexType +) + // ClientIndex defines a client index by a set of columns type ClientIndex struct { Columns []ColumnKey + Type IndexType } // ClientDBModel contains the client information needed to build a DatabaseModel @@ -161,6 +174,7 @@ func copyIndexes(src map[string][]ClientIndex) map[string][]ClientIndex { dst[table] = make([]ClientIndex, 0, len(indexSets)) for _, indexSet := range indexSets { indexSetCopy := ClientIndex{ + Type: indexSet.Type, Columns: make([]ColumnKey, len(indexSet.Columns)), } copy(indexSetCopy.Columns, indexSet.Columns)