You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ha...@apache.org on 2021/06/04 04:23:23 UTC

[skywalking-banyandb] 01/01: Add TraceSeries, IndexRule and IndexRuleBinding APIs

This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch api-schema
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git

commit da9942093cbea360d56439ea58535de08a5e4eaf
Author: Gao Hongtao <ha...@gmail.com>
AuthorDate: Fri Jun 4 12:20:18 2021 +0800

    Add TraceSeries, IndexRule and IndexRuleBinding APIs
    
    Signed-off-by: Gao Hongtao <ha...@gmail.com>
---
 api/fbs/v1/schema.fbs          | 121 ++++++++++
 api/fbs/v1/schema_generated.go | 504 +++++++++++++++++++++++++++++++++++++++++
 banyand/series/series.go       |   4 +
 3 files changed, 629 insertions(+)

diff --git a/api/fbs/v1/schema.fbs b/api/fbs/v1/schema.fbs
new file mode 100644
index 0000000..45b0451
--- /dev/null
+++ b/api/fbs/v1/schema.fbs
@@ -0,0 +1,121 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+include "database.fbs";
+
+namespace banyandb.v1;
+
+// TraceSeries represents a trace storage object
+table TraceSeries {
+    // metadata is the identity of a trace series
+    metadata:Metadata;
+    // duration determines how long a TraceSeries keeps its data
+    // unit    = "ns" | "ms" | "s" | "m" | "h" | "d" | "w" .
+    // duration: int_literal unit
+    duration:string;
+    // updated_at indicates when the TraceSeries is updated
+    updated_at:uint64;
+}
+
+// Catalog refers to a placement contains objects belonged to a particular data type
+enum Catalog:byte { Trace = 0, Log = 1, Metric = 2 }
+
+// IndexType determine the index structure under the hood
+enum IndexType:byte { Text = 0, Numerical = 1, ID = 2}
+
+// IndexObject defines who should be indexed.
+table IndexObject {
+    // fields are the combination that refers to an indexed object
+    // If the elements in fields are more than 1, the object will generate a multi-field index
+    // Caveat: All fields in a multi-field index MUST have an identical IndexTypee
+    fields:[string];
+    // type is the IndexType of this IndexObject.
+    type:IndexType;
+}
+
+// IndexRule defines how to generate indices based on IndexObject
+// IndexRule should bind to an IndexSubject through an IndexRuleBinding to generate proper indices.
+// Example: A trace entity wants to index fields: trace_id, service_name, endpoint_name, and latency.
+//          and service_name and endpoint_name would combine a multi-field index.
+// The index rule could be:
+// IndexRule {
+//     metadata: {
+//         name: sw_trace
+//         group: production
+//     }
+//     objects: [
+//        { 
+//            fields: [trace_id]
+//            type: ID
+//        },
+//        { 
+//            fields: [service_name, endpoint_name]
+//            type: Text
+//        },
+//        { 
+//            fields: latency]
+//            type: Numerical
+//        },
+//    ]
+//    update_at: .......
+// } 
+table IndexRule {
+    // metadata define the rule's identity
+    metadata:Metadata;
+    // objects refer to which fields should be indexed
+    objects:[IndexObject];
+    // updated_at indicates when the IndexRule is updated
+    updated_at:uint64;
+}
+
+// IndexSubject defines which subject(series) would generate indices
+// For example, if a TraceSeries's metadata is {name: sw_trace, group: production},
+//                in consequence, the IndexSubject is
+//                Index Subject {
+//                    catalog: Trace
+//                    series: {name: sw_trace, group: production}
+//                }
+table IndexSubject {
+    // catalog is where the subject/series belongs to
+    catalog:Catalog;
+    // series refers to a series in a particular catalog
+    series:Metadata;
+}
+
+
+// IndexRuleBinding is a bridge to connect an IndexRule to several IndexSubjects
+// This binding is valid between begin_at and expire_at, that provides flexible strategies
+// to control how to generate time series indices.
+table IndexRuleBinding {
+    // metadata is the identity of this binding
+    metadata:Metadata;
+    // rule_ref refers to the IndexRule
+    rule_ref:Metadata;
+    // subjects indicate which subjects will use such IndexRule to generate indices
+    subjects:[IndexSubject];
+    // begin_at is the timestamp, after which the binding will be active
+    begin_at:uint64;
+    // expire_at it the timestamp, after which the binding will be inactive
+    // expire_at must be larger than begin_at
+    expire_at:uint64;
+    // updated_at indicates when the IndexRuleBinding is updated
+    updated_at:uint64;
+}
+
+root_type TraceSeries;
+root_type IndexRule;
+root_type IndexRuleBinding;
diff --git a/api/fbs/v1/schema_generated.go b/api/fbs/v1/schema_generated.go
new file mode 100644
index 0000000..1108c7b
--- /dev/null
+++ b/api/fbs/v1/schema_generated.go
@@ -0,0 +1,504 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package v1
+
+import (
+	"strconv"
+
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Catalog int8
+
+const (
+	CatalogTrace  Catalog = 0
+	CatalogLog    Catalog = 1
+	CatalogMetric Catalog = 2
+)
+
+var EnumNamesCatalog = map[Catalog]string{
+	CatalogTrace:  "Trace",
+	CatalogLog:    "Log",
+	CatalogMetric: "Metric",
+}
+
+var EnumValuesCatalog = map[string]Catalog{
+	"Trace":  CatalogTrace,
+	"Log":    CatalogLog,
+	"Metric": CatalogMetric,
+}
+
+func (v Catalog) String() string {
+	if s, ok := EnumNamesCatalog[v]; ok {
+		return s
+	}
+	return "Catalog(" + strconv.FormatInt(int64(v), 10) + ")"
+}
+
+type IndexType int8
+
+const (
+	IndexTypeText      IndexType = 0
+	IndexTypeNumerical IndexType = 1
+	IndexTypeID        IndexType = 2
+)
+
+var EnumNamesIndexType = map[IndexType]string{
+	IndexTypeText:      "Text",
+	IndexTypeNumerical: "Numerical",
+	IndexTypeID:        "ID",
+}
+
+var EnumValuesIndexType = map[string]IndexType{
+	"Text":      IndexTypeText,
+	"Numerical": IndexTypeNumerical,
+	"ID":        IndexTypeID,
+}
+
+func (v IndexType) String() string {
+	if s, ok := EnumNamesIndexType[v]; ok {
+		return s
+	}
+	return "IndexType(" + strconv.FormatInt(int64(v), 10) + ")"
+}
+
+type TraceSeries struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsTraceSeries(buf []byte, offset flatbuffers.UOffsetT) *TraceSeries {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &TraceSeries{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func GetSizePrefixedRootAsTraceSeries(buf []byte, offset flatbuffers.UOffsetT) *TraceSeries {
+	n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
+	x := &TraceSeries{}
+	x.Init(buf, n+offset+flatbuffers.SizeUint32)
+	return x
+}
+
+func (rcv *TraceSeries) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TraceSeries) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *TraceSeries) Metadata(obj *Metadata) *Metadata {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(Metadata)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *TraceSeries) Duration() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *TraceSeries) UpdatedAt() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TraceSeries) MutateUpdatedAt(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(8, n)
+}
+
+func TraceSeriesStart(builder *flatbuffers.Builder) {
+	builder.StartObject(3)
+}
+func TraceSeriesAddMetadata(builder *flatbuffers.Builder, metadata flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(metadata), 0)
+}
+func TraceSeriesAddDuration(builder *flatbuffers.Builder, duration flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(duration), 0)
+}
+func TraceSeriesAddUpdatedAt(builder *flatbuffers.Builder, updatedAt uint64) {
+	builder.PrependUint64Slot(2, updatedAt, 0)
+}
+func TraceSeriesEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
+
+type IndexObject struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsIndexObject(buf []byte, offset flatbuffers.UOffsetT) *IndexObject {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &IndexObject{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func GetSizePrefixedRootAsIndexObject(buf []byte, offset flatbuffers.UOffsetT) *IndexObject {
+	n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
+	x := &IndexObject{}
+	x.Init(buf, n+offset+flatbuffers.SizeUint32)
+	return x
+}
+
+func (rcv *IndexObject) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *IndexObject) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *IndexObject) Fields(j int) []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.ByteVector(a + flatbuffers.UOffsetT(j*4))
+	}
+	return nil
+}
+
+func (rcv *IndexObject) FieldsLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *IndexObject) Type() IndexType {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		return IndexType(rcv._tab.GetInt8(o + rcv._tab.Pos))
+	}
+	return 0
+}
+
+func (rcv *IndexObject) MutateType(n IndexType) bool {
+	return rcv._tab.MutateInt8Slot(6, int8(n))
+}
+
+func IndexObjectStart(builder *flatbuffers.Builder) {
+	builder.StartObject(2)
+}
+func IndexObjectAddFields(builder *flatbuffers.Builder, fields flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(fields), 0)
+}
+func IndexObjectStartFieldsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func IndexObjectAddType(builder *flatbuffers.Builder, type_ IndexType) {
+	builder.PrependInt8Slot(1, int8(type_), 0)
+}
+func IndexObjectEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
+
+type IndexRule struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsIndexRule(buf []byte, offset flatbuffers.UOffsetT) *IndexRule {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &IndexRule{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func GetSizePrefixedRootAsIndexRule(buf []byte, offset flatbuffers.UOffsetT) *IndexRule {
+	n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
+	x := &IndexRule{}
+	x.Init(buf, n+offset+flatbuffers.SizeUint32)
+	return x
+}
+
+func (rcv *IndexRule) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *IndexRule) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *IndexRule) Metadata(obj *Metadata) *Metadata {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(Metadata)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *IndexRule) Objects(obj *IndexObject, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		x = rcv._tab.Indirect(x)
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *IndexRule) ObjectsLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *IndexRule) UpdatedAt() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *IndexRule) MutateUpdatedAt(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(8, n)
+}
+
+func IndexRuleStart(builder *flatbuffers.Builder) {
+	builder.StartObject(3)
+}
+func IndexRuleAddMetadata(builder *flatbuffers.Builder, metadata flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(metadata), 0)
+}
+func IndexRuleAddObjects(builder *flatbuffers.Builder, objects flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(objects), 0)
+}
+func IndexRuleStartObjectsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func IndexRuleAddUpdatedAt(builder *flatbuffers.Builder, updatedAt uint64) {
+	builder.PrependUint64Slot(2, updatedAt, 0)
+}
+func IndexRuleEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
+
+type IndexSubject struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsIndexSubject(buf []byte, offset flatbuffers.UOffsetT) *IndexSubject {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &IndexSubject{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func GetSizePrefixedRootAsIndexSubject(buf []byte, offset flatbuffers.UOffsetT) *IndexSubject {
+	n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
+	x := &IndexSubject{}
+	x.Init(buf, n+offset+flatbuffers.SizeUint32)
+	return x
+}
+
+func (rcv *IndexSubject) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *IndexSubject) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *IndexSubject) Catalog() Catalog {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return Catalog(rcv._tab.GetInt8(o + rcv._tab.Pos))
+	}
+	return 0
+}
+
+func (rcv *IndexSubject) MutateCatalog(n Catalog) bool {
+	return rcv._tab.MutateInt8Slot(4, int8(n))
+}
+
+func (rcv *IndexSubject) Series(obj *Metadata) *Metadata {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(Metadata)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func IndexSubjectStart(builder *flatbuffers.Builder) {
+	builder.StartObject(2)
+}
+func IndexSubjectAddCatalog(builder *flatbuffers.Builder, catalog Catalog) {
+	builder.PrependInt8Slot(0, int8(catalog), 0)
+}
+func IndexSubjectAddSeries(builder *flatbuffers.Builder, series flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(series), 0)
+}
+func IndexSubjectEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
+
+type IndexRuleBinding struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsIndexRuleBinding(buf []byte, offset flatbuffers.UOffsetT) *IndexRuleBinding {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &IndexRuleBinding{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func GetSizePrefixedRootAsIndexRuleBinding(buf []byte, offset flatbuffers.UOffsetT) *IndexRuleBinding {
+	n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
+	x := &IndexRuleBinding{}
+	x.Init(buf, n+offset+flatbuffers.SizeUint32)
+	return x
+}
+
+func (rcv *IndexRuleBinding) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *IndexRuleBinding) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *IndexRuleBinding) Metadata(obj *Metadata) *Metadata {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(Metadata)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *IndexRuleBinding) RuleRef(obj *Metadata) *Metadata {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(Metadata)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *IndexRuleBinding) Subjects(obj *IndexSubject, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		x = rcv._tab.Indirect(x)
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *IndexRuleBinding) SubjectsLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *IndexRuleBinding) BeginAt() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *IndexRuleBinding) MutateBeginAt(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(10, n)
+}
+
+func (rcv *IndexRuleBinding) ExpireAt() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *IndexRuleBinding) MutateExpireAt(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(12, n)
+}
+
+func (rcv *IndexRuleBinding) UpdatedAt() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *IndexRuleBinding) MutateUpdatedAt(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(14, n)
+}
+
+func IndexRuleBindingStart(builder *flatbuffers.Builder) {
+	builder.StartObject(6)
+}
+func IndexRuleBindingAddMetadata(builder *flatbuffers.Builder, metadata flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(metadata), 0)
+}
+func IndexRuleBindingAddRuleRef(builder *flatbuffers.Builder, ruleRef flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(ruleRef), 0)
+}
+func IndexRuleBindingAddSubjects(builder *flatbuffers.Builder, subjects flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(2, flatbuffers.UOffsetT(subjects), 0)
+}
+func IndexRuleBindingStartSubjectsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func IndexRuleBindingAddBeginAt(builder *flatbuffers.Builder, beginAt uint64) {
+	builder.PrependUint64Slot(3, beginAt, 0)
+}
+func IndexRuleBindingAddExpireAt(builder *flatbuffers.Builder, expireAt uint64) {
+	builder.PrependUint64Slot(4, expireAt, 0)
+}
+func IndexRuleBindingAddUpdatedAt(builder *flatbuffers.Builder, updatedAt uint64) {
+	builder.PrependUint64Slot(5, updatedAt, 0)
+}
+func IndexRuleBindingEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/banyand/series/series.go b/banyand/series/series.go
index de81f84..3e6de47 100644
--- a/banyand/series/series.go
+++ b/banyand/series/series.go
@@ -44,3 +44,7 @@ type Service interface {
 func NewService(ctx context.Context, db storage.Database) (Service, error) {
 	return nil, nil
 }
+
+// TODO: this interface should contains methods to access schema objects
+type SchemaRepo interface {
+}