Integrate BACKBEAT SDK and resolve KACHING license validation
Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
309
vendor/github.com/ipfs/go-datastore/key.go
generated
vendored
Normal file
309
vendor/github.com/ipfs/go-datastore/key.go
generated
vendored
Normal file
@@ -0,0 +1,309 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
dsq "github.com/ipfs/go-datastore/query"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
/*
|
||||
A Key represents the unique identifier of an object.
|
||||
Our Key scheme is inspired by file systems and Google App Engine key model.
|
||||
|
||||
Keys are meant to be unique across a system. Keys are hierarchical,
|
||||
incorporating more and more specific namespaces. Thus keys can be deemed
|
||||
'children' or 'ancestors' of other keys::
|
||||
|
||||
Key("/Comedy")
|
||||
Key("/Comedy/MontyPython")
|
||||
|
||||
Also, every namespace can be parametrized to embed relevant object
|
||||
information. For example, the Key `name` (most specific namespace) could
|
||||
include the object type::
|
||||
|
||||
Key("/Comedy/MontyPython/Actor:JohnCleese")
|
||||
Key("/Comedy/MontyPython/Sketch:CheeseShop")
|
||||
Key("/Comedy/MontyPython/Sketch:CheeseShop/Character:Mousebender")
|
||||
|
||||
*/
|
||||
type Key struct {
|
||||
string
|
||||
}
|
||||
|
||||
// NewKey constructs a key from string. it will clean the value.
|
||||
func NewKey(s string) Key {
|
||||
k := Key{s}
|
||||
k.Clean()
|
||||
return k
|
||||
}
|
||||
|
||||
// RawKey creates a new Key without safety checking the input. Use with care.
|
||||
func RawKey(s string) Key {
|
||||
// accept an empty string and fix it to avoid special cases
|
||||
// elsewhere
|
||||
if len(s) == 0 {
|
||||
return Key{"/"}
|
||||
}
|
||||
|
||||
// perform a quick sanity check that the key is in the correct
|
||||
// format, if it is not then it is a programmer error and it is
|
||||
// okay to panic
|
||||
if len(s) == 0 || s[0] != '/' || (len(s) > 1 && s[len(s)-1] == '/') {
|
||||
panic("invalid datastore key: " + s)
|
||||
}
|
||||
|
||||
return Key{s}
|
||||
}
|
||||
|
||||
// KeyWithNamespaces constructs a key out of a namespace slice.
|
||||
func KeyWithNamespaces(ns []string) Key {
|
||||
return NewKey(strings.Join(ns, "/"))
|
||||
}
|
||||
|
||||
// Clean up a Key, using path.Clean.
|
||||
func (k *Key) Clean() {
|
||||
switch {
|
||||
case len(k.string) == 0:
|
||||
k.string = "/"
|
||||
case k.string[0] == '/':
|
||||
k.string = path.Clean(k.string)
|
||||
default:
|
||||
k.string = path.Clean("/" + k.string)
|
||||
}
|
||||
}
|
||||
|
||||
// Strings is the string value of Key
|
||||
func (k Key) String() string {
|
||||
return k.string
|
||||
}
|
||||
|
||||
// Bytes returns the string value of Key as a []byte
|
||||
func (k Key) Bytes() []byte {
|
||||
return []byte(k.string)
|
||||
}
|
||||
|
||||
// Equal checks equality of two keys
|
||||
func (k Key) Equal(k2 Key) bool {
|
||||
return k.string == k2.string
|
||||
}
|
||||
|
||||
// Less checks whether this key is sorted lower than another.
|
||||
func (k Key) Less(k2 Key) bool {
|
||||
list1 := k.List()
|
||||
list2 := k2.List()
|
||||
for i, c1 := range list1 {
|
||||
if len(list2) < (i + 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
c2 := list2[i]
|
||||
if c1 < c2 {
|
||||
return true
|
||||
} else if c1 > c2 {
|
||||
return false
|
||||
}
|
||||
// c1 == c2, continue
|
||||
}
|
||||
|
||||
// list1 is shorter or exactly the same.
|
||||
return len(list1) < len(list2)
|
||||
}
|
||||
|
||||
// List returns the `list` representation of this Key.
|
||||
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").List()
|
||||
// ["Comedy", "MontyPythong", "Actor:JohnCleese"]
|
||||
func (k Key) List() []string {
|
||||
return strings.Split(k.string, "/")[1:]
|
||||
}
|
||||
|
||||
// Reverse returns the reverse of this Key.
|
||||
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Reverse()
|
||||
// NewKey("/Actor:JohnCleese/MontyPython/Comedy")
|
||||
func (k Key) Reverse() Key {
|
||||
l := k.List()
|
||||
r := make([]string, len(l))
|
||||
for i, e := range l {
|
||||
r[len(l)-i-1] = e
|
||||
}
|
||||
return KeyWithNamespaces(r)
|
||||
}
|
||||
|
||||
// Namespaces returns the `namespaces` making up this Key.
|
||||
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Namespaces()
|
||||
// ["Comedy", "MontyPython", "Actor:JohnCleese"]
|
||||
func (k Key) Namespaces() []string {
|
||||
return k.List()
|
||||
}
|
||||
|
||||
// BaseNamespace returns the "base" namespace of this key (path.Base(filename))
|
||||
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").BaseNamespace()
|
||||
// "Actor:JohnCleese"
|
||||
func (k Key) BaseNamespace() string {
|
||||
n := k.Namespaces()
|
||||
return n[len(n)-1]
|
||||
}
|
||||
|
||||
// Type returns the "type" of this key (value of last namespace).
|
||||
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Type()
|
||||
// "Actor"
|
||||
func (k Key) Type() string {
|
||||
return NamespaceType(k.BaseNamespace())
|
||||
}
|
||||
|
||||
// Name returns the "name" of this key (field of last namespace).
|
||||
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Name()
|
||||
// "JohnCleese"
|
||||
func (k Key) Name() string {
|
||||
return NamespaceValue(k.BaseNamespace())
|
||||
}
|
||||
|
||||
// Instance returns an "instance" of this type key (appends value to namespace).
|
||||
// NewKey("/Comedy/MontyPython/Actor").Instance("JohnClesse")
|
||||
// NewKey("/Comedy/MontyPython/Actor:JohnCleese")
|
||||
func (k Key) Instance(s string) Key {
|
||||
return NewKey(k.string + ":" + s)
|
||||
}
|
||||
|
||||
// Path returns the "path" of this key (parent + type).
|
||||
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Path()
|
||||
// NewKey("/Comedy/MontyPython/Actor")
|
||||
func (k Key) Path() Key {
|
||||
s := k.Parent().string + "/" + NamespaceType(k.BaseNamespace())
|
||||
return NewKey(s)
|
||||
}
|
||||
|
||||
// Parent returns the `parent` Key of this Key.
|
||||
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Parent()
|
||||
// NewKey("/Comedy/MontyPython")
|
||||
func (k Key) Parent() Key {
|
||||
n := k.List()
|
||||
if len(n) == 1 {
|
||||
return RawKey("/")
|
||||
}
|
||||
return NewKey(strings.Join(n[:len(n)-1], "/"))
|
||||
}
|
||||
|
||||
// Child returns the `child` Key of this Key.
|
||||
// NewKey("/Comedy/MontyPython").Child(NewKey("Actor:JohnCleese"))
|
||||
// NewKey("/Comedy/MontyPython/Actor:JohnCleese")
|
||||
func (k Key) Child(k2 Key) Key {
|
||||
switch {
|
||||
case k.string == "/":
|
||||
return k2
|
||||
case k2.string == "/":
|
||||
return k
|
||||
default:
|
||||
return RawKey(k.string + k2.string)
|
||||
}
|
||||
}
|
||||
|
||||
// ChildString returns the `child` Key of this Key -- string helper.
|
||||
// NewKey("/Comedy/MontyPython").ChildString("Actor:JohnCleese")
|
||||
// NewKey("/Comedy/MontyPython/Actor:JohnCleese")
|
||||
func (k Key) ChildString(s string) Key {
|
||||
return NewKey(k.string + "/" + s)
|
||||
}
|
||||
|
||||
// IsAncestorOf returns whether this key is a prefix of `other`
|
||||
// NewKey("/Comedy").IsAncestorOf("/Comedy/MontyPython")
|
||||
// true
|
||||
func (k Key) IsAncestorOf(other Key) bool {
|
||||
// equivalent to HasPrefix(other, k.string + "/")
|
||||
|
||||
if len(other.string) <= len(k.string) {
|
||||
// We're not long enough to be a child.
|
||||
return false
|
||||
}
|
||||
|
||||
if k.string == "/" {
|
||||
// We're the root and the other key is longer.
|
||||
return true
|
||||
}
|
||||
|
||||
// "other" starts with /k.string/
|
||||
return other.string[len(k.string)] == '/' && other.string[:len(k.string)] == k.string
|
||||
}
|
||||
|
||||
// IsDescendantOf returns whether this key contains another as a prefix.
|
||||
// NewKey("/Comedy/MontyPython").IsDescendantOf("/Comedy")
|
||||
// true
|
||||
func (k Key) IsDescendantOf(other Key) bool {
|
||||
return other.IsAncestorOf(k)
|
||||
}
|
||||
|
||||
// IsTopLevel returns whether this key has only one namespace.
|
||||
func (k Key) IsTopLevel() bool {
|
||||
return len(k.List()) == 1
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface,
|
||||
// keys are represented as JSON strings
|
||||
func (k Key) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(k.String())
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface,
|
||||
// keys will parse any value specified as a key to a string
|
||||
func (k *Key) UnmarshalJSON(data []byte) error {
|
||||
var key string
|
||||
if err := json.Unmarshal(data, &key); err != nil {
|
||||
return err
|
||||
}
|
||||
*k = NewKey(key)
|
||||
return nil
|
||||
}
|
||||
|
||||
// RandomKey returns a randomly (uuid) generated key.
|
||||
// RandomKey()
|
||||
// NewKey("/f98719ea086343f7b71f32ea9d9d521d")
|
||||
func RandomKey() Key {
|
||||
return NewKey(strings.Replace(uuid.New().String(), "-", "", -1))
|
||||
}
|
||||
|
||||
/*
|
||||
A Key Namespace is like a path element.
|
||||
A namespace can optionally include a type (delimited by ':')
|
||||
|
||||
> NamespaceValue("Song:PhilosopherSong")
|
||||
PhilosopherSong
|
||||
> NamespaceType("Song:PhilosopherSong")
|
||||
Song
|
||||
> NamespaceType("Music:Song:PhilosopherSong")
|
||||
Music:Song
|
||||
*/
|
||||
|
||||
// NamespaceType is the first component of a namespace. `foo` in `foo:bar`
|
||||
func NamespaceType(namespace string) string {
|
||||
parts := strings.Split(namespace, ":")
|
||||
if len(parts) < 2 {
|
||||
return ""
|
||||
}
|
||||
return strings.Join(parts[0:len(parts)-1], ":")
|
||||
}
|
||||
|
||||
// NamespaceValue returns the last component of a namespace. `baz` in `f:b:baz`
|
||||
func NamespaceValue(namespace string) string {
|
||||
parts := strings.Split(namespace, ":")
|
||||
return parts[len(parts)-1]
|
||||
}
|
||||
|
||||
// KeySlice attaches the methods of sort.Interface to []Key,
|
||||
// sorting in increasing order.
|
||||
type KeySlice []Key
|
||||
|
||||
func (p KeySlice) Len() int { return len(p) }
|
||||
func (p KeySlice) Less(i, j int) bool { return p[i].Less(p[j]) }
|
||||
func (p KeySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// EntryKeys
|
||||
func EntryKeys(e []dsq.Entry) []Key {
|
||||
ks := make([]Key, len(e))
|
||||
for i, e := range e {
|
||||
ks[i] = NewKey(e.Key)
|
||||
}
|
||||
return ks
|
||||
}
|
||||
Reference in New Issue
Block a user