├── .gitignore ├── LICENSE ├── README.md ├── api.go ├── bte └── errors.go ├── core.go ├── driver.go ├── examples └── insert_test.go ├── go.mod ├── go.sum ├── mash.go ├── utils.go └── v5api ├── btrdb.pb.go ├── btrdb.pb.gw.go ├── btrdb.proto ├── btrdb.swagger.json ├── btrdb_grpc.pb.go ├── gen.go └── include └── google └── api ├── annotations.proto └── http.proto /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | grpc-gateway 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause 2 | 3 | Copyright (c) 2016 Sam Kumar 4 | Copyright (c) 2016 Michael Andersen 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BTrDB golang bindings 2 | ===================== 3 | 4 | [![GoDoc](https://godoc.org/gopkg.in/btrdb.v5?status.svg)](http://godoc.org/gopkg.in/btrdb.v5) 5 | 6 | These are the go BTrDB bindings. This branch is compatible with version 5, a very recent rewrite of BTrDB. Note that it is likely you should be using the version 4 bindings of BTrDB as v5 is not widely released. 7 | 8 | You can read the API documentation and code examples by clicking the godoc button above. To import this package in your code, add 9 | 10 | ``` 11 | import "gopkg.in/BTrDB/btrdb.v5" 12 | ``` 13 | 14 | For more information about installing BTrDB, look at https://docs.smartgrid.store 15 | -------------------------------------------------------------------------------- /api.go: -------------------------------------------------------------------------------- 1 | // Package btrdb implementes a golang client driver for btrdb 2 | // 3 | // For functions returning value, version and error channels, please pay attention 4 | // to the following concurrency pattern: 5 | // 6 | // - The value channel must be completely consumed, always. 7 | // - The version channel need not be consumed if not required. Only one value will ever be written to the version channel. 8 | // - The error channel need not be read, but you cannot assume that there was not an error just because there were values 9 | // - You can defer reading the error channel until after the value channel is closed (it will be closed early on error). 10 | // 11 | // A good pattern is the following: 12 | // valchan, errchan = some.Method() 13 | // for v := range valchan { 14 | // do stuff 15 | // } 16 | // if err := <-errchan; err != nil { 17 | // handle error 18 | // } 19 | package btrdb 20 | 21 | import ( 22 | "context" 23 | "strings" 24 | 25 | pb "github.com/BTrDB/btrdb/v5/v5api" 26 | "github.com/pborman/uuid" 27 | ) 28 | 29 | // Maximum window of time that can be stored in a BTrDB tree 30 | const ( 31 | MinimumTime = -(16 << 56) 32 | MaximumTime = (48 << 56) 33 | ) 34 | 35 | //OptKV is a utility function for use in SetAnnotations or LookupStreams that 36 | //turns a list of arguments into a map[string]*string. Typical use: 37 | // OptKV("key","value", //Set or match key=vale 38 | // "key2", nil) //Delete or match key2=* 39 | //OptKV can also take a single map[string]string and return 40 | //a map[string]*string, e.g 41 | // OptKV(stream.Tags()) //Match exactly this set of tags 42 | func OptKV(iz ...interface{}) map[string]*string { 43 | if len(iz) == 1 { 44 | arg, ok := iz[0].(map[string]string) 45 | if !ok { 46 | panic("bad use of btrdb.OptKV: must have even number of arguments or a single map[string]string") 47 | } 48 | rv := make(map[string]*string) 49 | for k, v := range arg { 50 | cv := v 51 | rv[k] = &cv 52 | } 53 | return rv 54 | } 55 | if len(iz)%2 != 0 { 56 | panic("bad use of btrdb.OptKV: must have even number of arguments or a single map[string]string") 57 | } 58 | rv := make(map[string]*string) 59 | for i := 0; i < len(iz)/2; i++ { 60 | key, ok := iz[i*2].(string) 61 | if !ok { 62 | panic("bad use of btrdb.OptKV: even arguments must be string") 63 | } 64 | if iz[i*2+1] == nil { 65 | rv[key] = nil 66 | } else { 67 | val, ok := iz[i*2+1].(string) 68 | if !ok { 69 | panic("bad use of btrdb.OptKV: odd arguments must be string or nil") 70 | } 71 | rv[key] = &val 72 | } 73 | } 74 | return rv 75 | } 76 | 77 | //Stream is a handle on a Stream in BTrDB. Stream operations should be done through this object. 78 | type Stream struct { 79 | b *BTrDB 80 | 81 | uuid uuid.UUID 82 | 83 | knownToExist bool 84 | 85 | hasTags bool 86 | tags map[string]*string 87 | 88 | hasAnnotation bool 89 | annotations map[string]*string 90 | propertyVersion PropertyVersion 91 | 92 | hasCollection bool 93 | collection string 94 | } 95 | 96 | //StreamFromUUID creates a stream handle for use in stream operations. 97 | //it does not ensure that the stream exists, for that use Stream.Exists() 98 | func (b *BTrDB) StreamFromUUID(uu uuid.UUID) *Stream { 99 | return &Stream{ 100 | b: b, 101 | uuid: uu, 102 | } 103 | } 104 | 105 | func (s *Stream) refreshMeta(ctx context.Context) error { 106 | var ep *Endpoint 107 | var pver PropertyVersion 108 | var err error 109 | var coll string 110 | var tags map[string]*string 111 | var anns map[string]*string 112 | for s.b.TestEpError(ep, err) { 113 | ep, err = s.b.ReadEndpointFor(ctx, s.uuid) 114 | if err != nil { 115 | continue 116 | } 117 | coll, pver, tags, anns, _, err = ep.StreamInfo(ctx, s.uuid, false, true) 118 | if err != nil { 119 | continue 120 | } 121 | } 122 | if err == nil { 123 | s.collection = coll 124 | s.hasCollection = true 125 | s.tags = tags 126 | s.hasTags = true 127 | s.knownToExist = true 128 | s.annotations = anns 129 | s.propertyVersion = pver 130 | s.hasAnnotation = true 131 | return nil 132 | } 133 | return err 134 | } 135 | 136 | //Exists returns true if the stream exists. This is essential after using 137 | //StreamFromUUID as the stream may not exist, causing a 404 error on 138 | //later stream operations. Any operation that returns a stream from 139 | //collection and tags will have ensured the stream exists already. 140 | func (s *Stream) Exists(ctx context.Context) (bool, error) { 141 | if s.knownToExist { 142 | return true, nil 143 | } 144 | err := s.refreshMeta(ctx) 145 | if err != nil && (ToCodedError(err).Code == 404 || strings.Contains(err.Error(), "[404] stream does not exist")) { 146 | return false, nil 147 | } 148 | if err != nil { 149 | return false, err 150 | } 151 | return true, nil 152 | } 153 | 154 | //UUID returns the stream's UUID. The stream may nor may not exist yet, depending 155 | //on how the stream object was obtained. See also Stream.Exists() 156 | func (s *Stream) UUID() uuid.UUID { 157 | return s.uuid 158 | } 159 | 160 | //Tags returns the tags of the stream. It may require a round trip to the 161 | //server depending on how the stream was acquired. Do not modify the resulting 162 | //map as it is a reference to the internal stream state 163 | func (s *Stream) Tags(ctx context.Context) (map[string]*string, error) { 164 | if s.hasTags { 165 | return s.tags, nil 166 | } 167 | err := s.refreshMeta(ctx) 168 | if err != nil { 169 | return nil, err 170 | } 171 | return s.tags, nil 172 | } 173 | 174 | // If a stream has changed tags, you will need to call this to load the new tags 175 | func (s *Stream) Refresh(ctx context.Context) error { 176 | return s.refreshMeta(ctx) 177 | } 178 | 179 | //Annotations returns the annotations of the stream (and the annotation version). 180 | //It will always require a round trip to the server. If you are ok with stale 181 | //data and want a higher performance version, use Stream.CachedAnnotations(). 182 | //Do not modify the resulting map. 183 | func (s *Stream) Annotations(ctx context.Context) (map[string]*string, PropertyVersion, error) { 184 | err := s.refreshMeta(ctx) 185 | if err != nil { 186 | return nil, 0, err 187 | } 188 | return s.annotations, s.propertyVersion, nil 189 | } 190 | 191 | //CachedAnnotations returns the annotations of the stream, reusing previous 192 | //results if available, otherwise fetching from the server 193 | func (s *Stream) CachedAnnotations(ctx context.Context) (map[string]*string, PropertyVersion, error) { 194 | if !s.hasAnnotation { 195 | err := s.refreshMeta(ctx) 196 | if err != nil { 197 | return nil, 0, err 198 | } 199 | } 200 | return s.annotations, s.propertyVersion, nil 201 | } 202 | 203 | //Collection returns the collection of the stream. It may require a round 204 | //trip to the server depending on how the stream was acquired 205 | func (s *Stream) Collection(ctx context.Context) (string, error) { 206 | if s.hasCollection { 207 | return s.collection, nil 208 | } 209 | err := s.refreshMeta(ctx) 210 | if err != nil { 211 | return "", err 212 | } 213 | return s.collection, nil 214 | } 215 | 216 | //Version returns the current data version of the stream. This is not cached, 217 | //it queries each time. Take care that you do not intorduce races in your 218 | //code by assuming this function will always return the same vaue 219 | func (s *Stream) Version(ctx context.Context) (uint64, error) { 220 | var ep *Endpoint 221 | var err error 222 | 223 | for s.b.TestEpError(ep, err) { 224 | ep, err = s.b.ReadEndpointFor(ctx, s.uuid) 225 | if err != nil { 226 | continue 227 | } 228 | var ver uint64 229 | _, _, _, _, ver, err = ep.StreamInfo(ctx, s.uuid, true, false) 230 | if err != nil { 231 | continue 232 | } 233 | return ver, nil 234 | } 235 | return 0, err 236 | } 237 | 238 | //Count the total number of points currently in the stream, efficiently. 239 | func (s *Stream) Count(ctx context.Context, version uint64) (npoints uint64, err error) { 240 | points, _, echan := s.AlignedWindows(ctx, MinimumTime, MaximumTime, 62, version) 241 | for point := range points { 242 | npoints += point.Count 243 | } 244 | return npoints, <-echan 245 | } 246 | 247 | //InsertTV allows insertion of two equal length arrays, one containing times and 248 | //the other containing values. The arrays need not be sorted, but they must correspond 249 | //(i.e the first element of times is the time for the firt element of values). If the 250 | //arrays are larger than appropriate, this function will automatically chunk the inserts. 251 | //As a consequence, the insert is not necessarily atomic, but can be used with 252 | //very large arrays. 253 | func (s *Stream) InsertTV(ctx context.Context, times []int64, values []float64, p *InsertParams) error { 254 | if len(times) != len(values) { 255 | return ErrorWrongArgs 256 | } 257 | var ep *Endpoint 258 | var err error 259 | batchsize := 50000 260 | for len(times) > 0 { 261 | err = forceEp 262 | end := len(times) 263 | if end > batchsize { 264 | end = batchsize 265 | } 266 | thisBatchT := times[:end] 267 | thisBatchV := values[:end] 268 | //TODO pool or reuse 269 | pbraws := make([]*pb.RawPoint, len(thisBatchT)) 270 | for i := 0; i < len(thisBatchT); i++ { 271 | pbraws[i] = &pb.RawPoint{ 272 | Time: thisBatchT[i], 273 | Value: thisBatchV[i], 274 | } 275 | } 276 | for s.b.TestEpError(ep, err) { 277 | ep, err = s.b.EndpointFor(ctx, s.uuid) 278 | if err != nil { 279 | continue 280 | } 281 | err = ep.Insert(ctx, s.uuid, pbraws, p) 282 | } 283 | if err != nil { 284 | return err 285 | } 286 | times = times[end:] 287 | values = values[end:] 288 | } 289 | return nil 290 | } 291 | 292 | //Flush writes the stream buffers out to persistent storage 293 | func (s *Stream) Flush(ctx context.Context) error { 294 | var ep *Endpoint 295 | var err error 296 | for s.b.TestEpError(ep, err) { 297 | ep, err = s.b.EndpointFor(ctx, s.uuid) 298 | if err != nil { 299 | continue 300 | } 301 | err = ep.Flush(ctx, s.uuid) 302 | } 303 | if err != nil { 304 | return err 305 | } 306 | return nil 307 | } 308 | 309 | //Obliterate completely removes a stream. This operation is immediate but 310 | //the space will only be freed slowly 311 | func (s *Stream) Obliterate(ctx context.Context) error { 312 | var ep *Endpoint 313 | var err error 314 | for s.b.TestEpError(ep, err) { 315 | ep, err = s.b.EndpointFor(ctx, s.uuid) 316 | if err != nil { 317 | continue 318 | } 319 | err = ep.Obliterate(ctx, s.uuid) 320 | } 321 | if err != nil { 322 | return err 323 | } 324 | return nil 325 | } 326 | 327 | //CompareAndSetAnnotation will make the changes in the given map as long as the 328 | //annotation version matches. To remove a key, specify it in the "remove" list 329 | func (s *Stream) CompareAndSetAnnotation(ctx context.Context, expected PropertyVersion, changes map[string]*string, remove []string) error { 330 | var ep *Endpoint 331 | var err error 332 | for s.b.TestEpError(ep, err) { 333 | ep, err = s.b.EndpointFor(ctx, s.uuid) 334 | if err != nil { 335 | continue 336 | } 337 | err = ep.SetStreamAnnotations(ctx, s.uuid, expected, changes, remove) 338 | } 339 | if err != nil { 340 | return err 341 | } 342 | return nil 343 | } 344 | 345 | //CompareAndSetTags will update a stream's collection name and tags if the property version matches 346 | func (s *Stream) CompareAndSetTags(ctx context.Context, expected PropertyVersion, collection string, changes map[string]*string) error { 347 | var ep *Endpoint 348 | var err error 349 | for s.b.TestEpError(ep, err) { 350 | ep, err = s.b.EndpointFor(ctx, s.uuid) 351 | if err != nil { 352 | continue 353 | } 354 | err = ep.SetStreamTags(ctx, s.uuid, expected, collection, changes) 355 | } 356 | if err != nil { 357 | return err 358 | } 359 | return nil 360 | } 361 | 362 | func (s *Stream) InsertGeneric(ctx context.Context, vals []RawPoint, p *InsertParams) error { 363 | var ep *Endpoint 364 | var err error 365 | batchsize := 50000 366 | for len(vals) > 0 { 367 | err = forceEp 368 | end := len(vals) 369 | if end > batchsize { 370 | end = batchsize 371 | } 372 | thisBatch := vals[:end] 373 | //TODO pool or reuse 374 | pbraws := make([]*pb.RawPoint, len(thisBatch)) 375 | for idx, p := range thisBatch { 376 | pbraws[idx] = &pb.RawPoint{ 377 | Time: p.Time, 378 | Value: p.Value, 379 | } 380 | } 381 | for s.b.TestEpError(ep, err) { 382 | ep, err = s.b.EndpointFor(ctx, s.uuid) 383 | if err != nil { 384 | continue 385 | } 386 | err = ep.InsertGeneric(ctx, s.uuid, pbraws, p) 387 | } 388 | if err != nil { 389 | return err 390 | } 391 | vals = vals[end:] 392 | } 393 | return nil 394 | 395 | } 396 | 397 | //InsertUnique acts like Insert, but allows specifying a merge policy. 398 | func (s *Stream) InsertUnique(ctx context.Context, vals []RawPoint, mp MergePolicy) error { 399 | return s.InsertGeneric(ctx, vals, &InsertParams{MergePolicy: mp}) 400 | } 401 | 402 | //Insert inserts the given array of RawPoint values. If the 403 | //array is larger than appropriate, this function will automatically chunk the inserts. 404 | //As a consequence, the insert is not necessarily atomic, but can be used with 405 | //very large arrays. 406 | func (s *Stream) Insert(ctx context.Context, vals []RawPoint) error { 407 | return s.InsertGeneric(ctx, vals, nil) 408 | } 409 | 410 | //InsertF will call the given time and val functions to get each value of the 411 | //insertion. It is similar to InsertTV but may require less allocations if 412 | //your data is already in a different data structure. If the 413 | //size is larger than appropriate, this function will automatically chunk the inserts. 414 | //As a consequence, the insert is not necessarily atomic, but can be used with 415 | //very large size. 416 | func (s *Stream) InsertF(ctx context.Context, length int, time func(int) int64, val func(int) float64, p *InsertParams) error { 417 | var ep *Endpoint 418 | var err error 419 | batchsize := 50000 420 | fidx := 0 421 | for fidx < length { 422 | err = forceEp 423 | tsize := length - fidx 424 | if tsize > batchsize { 425 | tsize = batchsize 426 | } 427 | //TODO pool or reuse 428 | pbraws := make([]*pb.RawPoint, tsize) 429 | for i := 0; i < tsize; i++ { 430 | pbraws[i] = &pb.RawPoint{ 431 | Time: time(fidx), 432 | Value: val(fidx), 433 | } 434 | fidx++ 435 | } 436 | for s.b.TestEpError(ep, err) { 437 | ep, err = s.b.EndpointFor(ctx, s.uuid) 438 | if err != nil { 439 | continue 440 | } 441 | err = ep.Insert(ctx, s.uuid, pbraws, p) 442 | } 443 | if err != nil { 444 | return err 445 | } 446 | } 447 | return nil 448 | } 449 | 450 | //RawValues reads raw values from BTrDB. The returned RawPoint channel must be fully consumed. 451 | func (s *Stream) RawValues(ctx context.Context, start int64, end int64, version uint64) (chan RawPoint, chan uint64, chan error) { 452 | var ep *Endpoint 453 | var err error 454 | for s.b.TestEpError(ep, err) { 455 | ep, err = s.b.ReadEndpointFor(ctx, s.uuid) 456 | if err != nil { 457 | continue 458 | } 459 | rvchan, rvvchan, errchan := ep.RawValues(ctx, s.uuid, start, end, version) 460 | return rvchan, rvvchan, s.b.SnoopEpErr(ep, errchan) 461 | } 462 | if err == nil { 463 | panic("Please report this") 464 | } 465 | rv := make(chan RawPoint) 466 | close(rv) 467 | rvv := make(chan uint64) 468 | close(rvv) 469 | errc := make(chan error, 1) 470 | errc <- err 471 | close(errc) 472 | return rv, rvv, errc 473 | } 474 | 475 | //AlignedWindows reads power-of-two aligned windows from BTrDB. It is faster than Windows(). Each returned window will be 2^pointwidth nanoseconds 476 | //long, starting at start. Note that start is inclusive, but end is exclusive. That is, results will be returned for all windows that start 477 | //in the interval [start, end). If end < start+2^pointwidth you will not get any results. If start and end are not powers of two, the bottom 478 | //pointwidth bits will be cleared. Each window will contain statistical summaries of the window. Statistical points with count == 0 will be 479 | //omitted. 480 | func (s *Stream) AlignedWindows(ctx context.Context, start int64, end int64, pointwidth uint8, version uint64) (chan StatPoint, chan uint64, chan error) { 481 | var ep *Endpoint 482 | var err error 483 | for s.b.TestEpError(ep, err) { 484 | ep, err = s.b.ReadEndpointFor(ctx, s.uuid) 485 | if err != nil { 486 | continue 487 | } 488 | rvchan, rvvchan, errchan := ep.AlignedWindows(ctx, s.uuid, start, end, pointwidth, version) 489 | return rvchan, rvvchan, s.b.SnoopEpErr(ep, errchan) 490 | } 491 | if err == nil { 492 | panic("Please report this") 493 | } 494 | rv := make(chan StatPoint) 495 | close(rv) 496 | rvv := make(chan uint64) 497 | close(rvv) 498 | errc := make(chan error, 1) 499 | errc <- err 500 | close(errc) 501 | return rv, rvv, errc 502 | } 503 | 504 | //Windows returns arbitrary precision windows from BTrDB. It is slower than AlignedWindows, but still significantly faster than RawValues. Each returned 505 | //window will be width nanoseconds long. start is inclusive, but end is exclusive (e.g if end < start+width you will get no results). That is, results will 506 | //be returned for all windows that start at a time less than the end timestamp. If (end - start) is not a multiple of width, then end will be decreased to 507 | //the greatest value less than end such that (end - start) is a multiple of width (i.e., we set end = start + width * floordiv(end - start, width). The depth 508 | //parameter is an optimization that can be used to speed up queries on fast queries. Each window will be accurate to 2^depth nanoseconds. If depth is zero, 509 | //the results are accurate to the nanosecond. On a dense stream for large windows, this accuracy may not be required. For example for a window of a day, +- one 510 | //second may be appropriate, so a depth of 30 can be specified. This is much faster to execute on the database side. The StatPoint channel MUST be fully 511 | //consumed. 512 | func (s *Stream) Windows(ctx context.Context, start int64, end int64, width uint64, depth uint8, version uint64) (chan StatPoint, chan uint64, chan error) { 513 | var ep *Endpoint 514 | var err error 515 | for s.b.TestEpError(ep, err) { 516 | ep, err = s.b.ReadEndpointFor(ctx, s.uuid) 517 | if err != nil { 518 | continue 519 | } 520 | rvchan, rvvchan, errchan := ep.Windows(ctx, s.uuid, start, end, width, depth, version) 521 | return rvchan, rvvchan, s.b.SnoopEpErr(ep, errchan) 522 | } 523 | if err == nil { 524 | panic("Please report this") 525 | } 526 | rv := make(chan StatPoint) 527 | close(rv) 528 | rvv := make(chan uint64) 529 | close(rvv) 530 | errc := make(chan error, 1) 531 | errc <- err 532 | close(errc) 533 | return rv, rvv, errc 534 | } 535 | 536 | //DeleteRange will delete all points between start (inclusive) and end (exclusive). Note that BTrDB has persistent 537 | //multiversioning, so the deleted points can still be accessed on an older version of the stream 538 | //returns the version of the stream and any error 539 | func (s *Stream) DeleteRange(ctx context.Context, start int64, end int64) (ver uint64, err error) { 540 | var ep *Endpoint 541 | for s.b.TestEpError(ep, err) { 542 | ep, err = s.b.EndpointFor(ctx, s.uuid) 543 | if err != nil { 544 | continue 545 | } 546 | ver, err = ep.DeleteRange(ctx, s.uuid, start, end) 547 | } 548 | return 549 | } 550 | 551 | //Nearest will return the nearest point to the given time. If backward is false, the returned point 552 | //will be >= time. If backward is true, the returned point will be = after. To find the earliest point that exists in a stream, use: 568 | // stream.Earliest(context.Background(), btrdb.MinimumTime, 0). 569 | func (s *Stream) Earliest(ctx context.Context, after int64, version uint64) (rv RawPoint, ver uint64, err error) { 570 | return s.Nearest(ctx, after, version, false) 571 | } 572 | 573 | // Latest returns the point nearest to the specified end time, searching backward such that the 574 | // returned point will be < before. To find the latest point that exists in a stream, use: 575 | // stream.Latest(context.Background(), btrdb.MaximumTime-1, 0). Another common usage is to find the 576 | // point closest to now: stream.Latest(context.Background(), time.Now().UnixNano(), 0) 577 | func (s *Stream) Latest(ctx context.Context, before int64, version uint64) (rv RawPoint, ver uint64, err error) { 578 | return s.Nearest(ctx, before, version, true) 579 | } 580 | 581 | // Changes returns the time intervals that have been altered between the two given versions. The precision of these time intervals is given by 582 | // resolution (in log nanoseconds). The intervals will be rounded bigger if resolution is >0 but the calculation will be faster 583 | func (s *Stream) Changes(ctx context.Context, fromVersion uint64, toVersion uint64, resolution uint8) (crv chan ChangedRange, cver chan uint64, cerr chan error) { 584 | var ep *Endpoint 585 | var err error 586 | for s.b.TestEpError(ep, err) { 587 | ep, err = s.b.ReadEndpointFor(ctx, s.uuid) 588 | if err != nil { 589 | continue 590 | } 591 | crchan, cvchan, errchan := ep.Changes(ctx, s.uuid, fromVersion, toVersion, resolution) 592 | return crchan, cvchan, s.b.SnoopEpErr(ep, errchan) 593 | } 594 | if err == nil { 595 | panic("Please report this") 596 | } 597 | rv := make(chan ChangedRange) 598 | close(rv) 599 | cver = make(chan uint64) 600 | close(cver) 601 | errc := make(chan error, 1) 602 | errc <- err 603 | close(errc) 604 | return rv, cver, errc 605 | } 606 | 607 | //GetCompactionConfig returns the compaction configuration for the given stream 608 | func (s *Stream) GetCompactionConfig(ctx context.Context) (cfg *CompactionConfig, majVersion uint64, err error) { 609 | var ep *Endpoint 610 | for s.b.TestEpError(ep, err) { 611 | ep, err = s.b.EndpointFor(ctx, s.uuid) 612 | if err != nil { 613 | continue 614 | } 615 | cfg, majVersion, err = ep.GetCompactionConfig(ctx, s.uuid) 616 | } 617 | if err != nil { 618 | return nil, 0, err 619 | } 620 | return 621 | } 622 | 623 | //SetCompactionConfig sets the compaction configuration for the given stream 624 | func (s *Stream) SetCompactionConfig(ctx context.Context, cfg *CompactionConfig) (err error) { 625 | var ep *Endpoint 626 | for s.b.TestEpError(ep, err) { 627 | ep, err = s.b.EndpointFor(ctx, s.uuid) 628 | if err != nil { 629 | continue 630 | } 631 | err = ep.SetCompactionConfig(ctx, s.uuid, cfg) 632 | } 633 | return 634 | } 635 | 636 | //Create a new stream with the given uuid, collection tags and annotations 637 | func (b *BTrDB) Create(ctx context.Context, uu uuid.UUID, collection string, tags map[string]*string, annotations map[string]*string) (*Stream, error) { 638 | var ep *Endpoint 639 | var err error 640 | for b.TestEpError(ep, err) { 641 | ep, err = b.EndpointFor(ctx, uu) 642 | if err != nil { 643 | continue 644 | } 645 | err = ep.Create(ctx, uu, collection, tags, annotations) 646 | } 647 | if err != nil { 648 | return nil, err 649 | } 650 | rv := &Stream{ 651 | uuid: uu, 652 | collection: collection, 653 | hasCollection: true, 654 | tags: make(map[string]*string), 655 | hasTags: true, 656 | annotations: make(map[string]*string), 657 | hasAnnotation: true, 658 | propertyVersion: 0, 659 | b: b, 660 | } 661 | //Copy the maps in case user messes with parameters 662 | for k, v := range tags { 663 | rv.tags[k] = v 664 | } 665 | for k, v := range annotations { 666 | rv.annotations[k] = v 667 | } 668 | return rv, nil 669 | } 670 | 671 | //ListCollections returns all collections on the server having the given prefix. It is preferable to use the streaming form 672 | func (b *BTrDB) ListCollections(ctx context.Context, prefix string) ([]string, error) { 673 | rv := []string{} 674 | rvc, rve := b.StreamingListCollections(ctx, prefix) 675 | for v := range rvc { 676 | rv = append(rv, v) 677 | } 678 | if err := <-rve; err != nil { 679 | return nil, err 680 | } 681 | return rv, nil 682 | } 683 | 684 | //List all the collections with the given prefix, without loading them all into memory 685 | func (b *BTrDB) StreamingListCollections(ctx context.Context, prefix string) (chan string, chan error) { 686 | var ep *Endpoint 687 | var err error 688 | for b.TestEpError(ep, err) { 689 | ep, err = b.GetAnyEndpoint(ctx) 690 | if err != nil { 691 | continue 692 | } 693 | streamchan, errchan := ep.ListCollections(ctx, prefix) 694 | return streamchan, b.SnoopEpErr(ep, errchan) 695 | } 696 | if err == nil { 697 | panic("Please report this") 698 | } 699 | rv := make(chan string) 700 | close(rv) 701 | errc := make(chan error, 1) 702 | errc <- err 703 | close(errc) 704 | return rv, errc 705 | } 706 | 707 | func (b *BTrDB) Info(ctx context.Context) (*MASH, error) { 708 | var ep *Endpoint 709 | var err error 710 | var rv *MASH 711 | for b.TestEpError(ep, err) { 712 | ep, err = b.GetAnyEndpoint(ctx) 713 | if err != nil { 714 | continue 715 | } 716 | rv, _, err = ep.Info(ctx) 717 | } 718 | return rv, err 719 | } 720 | 721 | func (b *BTrDB) StreamingLookupStreams(ctx context.Context, collection string, isCollectionPrefix bool, tags map[string]*string, annotations map[string]*string) (chan *Stream, chan error) { 722 | var ep *Endpoint 723 | var err error 724 | for b.TestEpError(ep, err) { 725 | ep, err = b.GetAnyEndpoint(ctx) 726 | if err != nil { 727 | continue 728 | } 729 | streamchan, errchan := ep.LookupStreams(ctx, collection, isCollectionPrefix, tags, annotations, b) 730 | return streamchan, b.SnoopEpErr(ep, errchan) 731 | } 732 | if err == nil { 733 | panic("Please report this") 734 | } 735 | rv := make(chan *Stream) 736 | close(rv) 737 | errc := make(chan error, 1) 738 | errc <- err 739 | close(errc) 740 | return rv, errc 741 | } 742 | 743 | //Execute a metadata SQL query but buffer the results in memory 744 | func (b *BTrDB) SQLQuery(ctx context.Context, query string, params ...string) ([]map[string]interface{}, error) { 745 | rv := []map[string]interface{}{} 746 | cv, ce := b.StreamingSQLQuery(ctx, query, params...) 747 | for s := range cv { 748 | rv = append(rv, s) 749 | } 750 | if err := <-ce; err != nil { 751 | return nil, err 752 | } 753 | return rv, nil 754 | } 755 | 756 | //Execute a metadata SQL query 757 | func (b *BTrDB) StreamingSQLQuery(ctx context.Context, query string, params ...string) (chan map[string]interface{}, chan error) { 758 | var ep *Endpoint 759 | var err error 760 | for b.TestEpError(ep, err) { 761 | ep, err = b.GetAnyEndpoint(ctx) 762 | if err != nil { 763 | continue 764 | } 765 | streamchan, errchan := ep.SQLQuery(ctx, query, params) 766 | return streamchan, b.SnoopEpErr(ep, errchan) 767 | } 768 | if err == nil { 769 | panic("Please report this") 770 | } 771 | rv := make(chan map[string]interface{}) 772 | close(rv) 773 | errc := make(chan error, 1) 774 | errc <- err 775 | close(errc) 776 | return rv, errc 777 | } 778 | 779 | func (b *BTrDB) LookupStreams(ctx context.Context, collection string, isCollectionPrefix bool, tags map[string]*string, annotations map[string]*string) ([]*Stream, error) { 780 | rv := []*Stream{} 781 | cv, ce := b.StreamingLookupStreams(ctx, collection, isCollectionPrefix, tags, annotations) 782 | for s := range cv { 783 | rv = append(rv, s) 784 | } 785 | if err := <-ce; err != nil { 786 | return nil, err 787 | } 788 | return rv, nil 789 | } 790 | 791 | func (b *BTrDB) GetMetadataUsage(ctx context.Context, prefix string) (tags map[string]int, annotations map[string]int, err error) { 792 | var ep *Endpoint 793 | for b.TestEpError(ep, err) { 794 | ep, err = b.GetAnyEndpoint(ctx) 795 | if err != nil { 796 | continue 797 | } 798 | tags, annotations, err = ep.GetMetadataUsage(ctx, prefix) 799 | } 800 | return tags, annotations, err 801 | } 802 | 803 | // Execute a wide raw values query. 804 | func (b *BTrDB) WValues(ctx context.Context, streams []*Stream, start int64, end int64, version uint64) (chan RawPointVec, chan uint64, chan error) { 805 | return b.WValuesAligned(ctx, streams, start, end, version, 0) 806 | } 807 | 808 | // Execute a wide raw value query with time alignment. 809 | func (b *BTrDB) WValuesAligned(ctx context.Context, streams []*Stream, start int64, end int64, version uint64, period int64) (chan RawPointVec, chan uint64, chan error) { 810 | var ep *Endpoint 811 | var err error 812 | 813 | m := make(map[*Endpoint][]uuid.UUID) 814 | pvc := make(chan RawPointVec) 815 | rvc := make(chan uint64, 1) 816 | evc := make(chan error, 1) 817 | for _, s := range streams { 818 | for s.b.TestEpError(ep, err) { 819 | ep, err = s.b.ReadEndpointFor(ctx, s.uuid) 820 | if err != nil { 821 | continue 822 | } 823 | } 824 | m[ep] = append(m[ep], s.uuid) 825 | } 826 | for ep, ids := range m { 827 | ep.MultiRawValues(ctx, ids, pvc, rvc, evc, start, end, version, period) 828 | } 829 | return pvc, rvc, evc 830 | } 831 | -------------------------------------------------------------------------------- /bte/errors.go: -------------------------------------------------------------------------------- 1 | package bte 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "runtime/debug" 7 | 8 | "context" 9 | ) 10 | 11 | // This defines all the errors that BTrDB can throw 12 | type bTE struct { 13 | code int 14 | reason string 15 | cause error 16 | } 17 | 18 | type BTE interface { 19 | error 20 | Code() int 21 | Reason() string 22 | Cause() error 23 | } 24 | 25 | func (bte *bTE) Code() int { 26 | return bte.code 27 | } 28 | 29 | func (bte *bTE) Reason() string { 30 | return bte.reason 31 | } 32 | 33 | func (bte *bTE) Cause() error { 34 | return bte.cause 35 | } 36 | 37 | func (bte *bTE) WrappedErrors() []error { 38 | return []error{bte.cause} 39 | } 40 | func (bte *bTE) Error() string { 41 | return fmt.Sprintf("(%d: %s)", bte.code, bte.reason) 42 | } 43 | 44 | func MaybeWrap(err error) BTE { 45 | bt, ok := err.(BTE) 46 | if ok { 47 | return bt 48 | } 49 | return Err(GenericError, err.Error()) 50 | } 51 | 52 | // Error codes: 53 | // 400+ normal user errors 54 | // 500+ abnormal errors that sysadmin should be notified about 55 | 56 | func Err(code int, reason string) BTE { 57 | if code >= 500 { 58 | fmt.Fprintf(os.Stderr, "\n\n=== %d code error ===\nreason: %s\n", code, reason) 59 | debug.PrintStack() 60 | fmt.Fprintf(os.Stderr, "====\n\n") 61 | } 62 | return &bTE{ 63 | code: code, 64 | reason: reason, 65 | cause: nil, 66 | } 67 | } 68 | func ErrF(code int, reasonz string, args ...interface{}) BTE { 69 | reason := fmt.Sprintf(reasonz, args...) 70 | if code >= 500 { 71 | fmt.Fprintf(os.Stderr, "\n\n=== %d code error ===\nreason: %s\n", code, reason) 72 | debug.PrintStack() 73 | fmt.Fprintf(os.Stderr, "====\n\n") 74 | } 75 | return &bTE{ 76 | code: code, 77 | reason: reason, 78 | cause: nil, 79 | } 80 | } 81 | func ErrW(code int, reason string, cause error) BTE { 82 | if code >= 500 { 83 | fmt.Fprintf(os.Stderr, "\n\n=== %d code error ===\nreason: %s\nbecause: %s", code, reason, cause.Error()) 84 | debug.PrintStack() 85 | fmt.Fprintf(os.Stderr, "====\n\n") 86 | } 87 | scause := "" 88 | if cause != nil { 89 | scause = cause.Error() 90 | } 91 | return &bTE{ 92 | code: code, 93 | reason: fmt.Sprintf("%s (%s)", reason, scause), 94 | cause: cause, 95 | } 96 | } 97 | func CtxE(ctx context.Context) BTE { 98 | if ctx.Err() == nil { 99 | return nil 100 | } 101 | return &bTE{ 102 | code: ContextError, 103 | reason: fmt.Sprintf("%s (%s)", "context error", ctx.Err()), 104 | cause: ctx.Err(), 105 | } 106 | } 107 | func Chan(e BTE) chan BTE { 108 | rv := make(chan BTE, 1) 109 | rv <- e //buffered 110 | return rv 111 | } 112 | 113 | //Context errors cascade quite a bit and tend to cause duplicate errors 114 | //in the return channel. Try not to leak goroutiens by] 115 | //blocking on them 116 | func ChkContextError(ctx context.Context, rve chan BTE) bool { 117 | if ctx.Err() != nil { 118 | select { 119 | case rve <- CtxE(ctx): 120 | default: 121 | } 122 | return true 123 | } 124 | return false 125 | } 126 | func NoBlockError(e BTE, ch chan BTE) { 127 | if e != nil { 128 | select { 129 | case ch <- e: 130 | default: 131 | } 132 | } 133 | } 134 | 135 | // If you ask for next/prev point but there isn't one 136 | const NoSuchPoint = 401 137 | 138 | // Things like user timeout 139 | const ContextError = 402 140 | 141 | // Like tree depth 142 | const InsertFailure = 403 143 | 144 | const NoSuchStream = 404 145 | 146 | // We don't have a write lock for this stream 147 | const WrongEndpoint = 405 148 | 149 | // The stream already exists 150 | const StreamExists = 406 151 | 152 | // Collection name is invalid 153 | const InvalidCollection = 407 154 | 155 | // Tag key is invalid 156 | const InvalidTagKey = 408 157 | 158 | // Tag value is invalid 159 | const InvalidTagValue = 409 160 | 161 | // Just in case 162 | const AwesomenessExceedsThreshold = 410 163 | 164 | // For commands accepting a limit argument, the passed limit is invalid 165 | const InvalidLimit = 411 166 | 167 | // If a set of tags is given to identify a single stream, but fails to do 168 | // so 169 | const AmbiguousTags = 412 170 | 171 | // The start/end times are invalid 172 | const InvalidTimeRange = 413 173 | 174 | // The insertion is too big (that's what she said) 175 | const InsertTooBig = 414 176 | 177 | // Point widths are [0, 64) 178 | const InvalidPointWidth = 415 179 | 180 | // When an error has no code 181 | const GenericError = 416 182 | 183 | // When create() is called and the uuid is the same as an existing stream 184 | const SameStream = 417 185 | 186 | // When create() is called and although the uuid is different, the tags are not unique 187 | const AmbiguousStream = 418 188 | 189 | // When a write op on an unmapped UUID is attempted 190 | const ClusterDegraded = 419 191 | 192 | // Just in case this is required after Prop 64 193 | const BlazeIt = 420 194 | 195 | // Generated in drivers when the arguments are the wrong type or length 196 | const WrongArgs = 421 197 | 198 | // Annotations cannot exceed 2MB 199 | const AnnotationTooBig = 422 200 | 201 | // The annotation version did not match 202 | const AnnotationVersionMismatch = 423 203 | 204 | // Fault injection is disabled (you need $BTRDB_ENABLE_FAULT_INJECTON=YES) 205 | const FaultInjectionDisabled = 424 206 | 207 | // Returned when you try insert NaN or Inf values 208 | const BadValue = 425 209 | 210 | // Used when the cluster is extremely overloaded and is shedding load to 211 | // maintain stability 212 | const ResourceDepleted = 426 213 | 214 | // Returned when you try do changed ranges with bad versions 215 | const InvalidVersions = 427 216 | 217 | // Returned when the etcd cluster is unhealthy 218 | const EtcdFailure = 428 219 | 220 | // Returned if you try create a stream with a uuid that is the same as a 221 | // previously deleted stream 222 | const ReusedUUID = 429 223 | 224 | // Returned if you try delete a stream while its attributes are being 225 | // modified 226 | const ConcurrentModification = 430 227 | 228 | // Returned if you try to obliterate a stream on a node where 229 | // BTRDB_ENABLE_OBLITERATE is not set to "YES" 230 | const ObliterateDisabled = 431 231 | 232 | // Generic error from ceph 233 | const CephError = 432 234 | 235 | // Means that a node ID is reused, as of BTrDB 4.8 a node id must be unique 236 | const NodeExisted = 433 237 | 238 | // Generic error returned when journalling 239 | const JournalError = 434 240 | 241 | // Errors when manipulating the manifest 242 | const ManifestError = 435 243 | 244 | // Returned when there is a duplicate device 245 | const ManifestDeviceDuplicated = 436 246 | 247 | // User does not have the right permissions 248 | const Unauthorized = 437 249 | 250 | // You sent the wrong thing to an API endpoint 251 | const InvalidParameter = 438 252 | 253 | // When you try delete a manifest device that does not exist 254 | const ManifestDeviceDoesntExist = 439 255 | 256 | // Metadata database failure (like connection failure) 257 | const MetadataConnectionError = 440 258 | 259 | // Generic error when bad parameters are passed to metadata db 260 | const BadSQLValue = 441 261 | 262 | // Error when something other than a stream already exists 263 | const AlreadyExists = 442 264 | 265 | // Error when a key in a parameter map is missing 266 | const MissingParameter = 443 267 | 268 | // Error when there is a key in a parameter map that is unrecognized 269 | const UnrecognizedParameter = 444 270 | 271 | // Error when a non-stream object is not found 272 | const ObjectNotFound = 445 273 | 274 | // Error when you try delete an object but it is still in use 275 | const ObjectInUse = 446 276 | 277 | // When you try an operation that is not permitted by the current configuration 278 | const OperationNotAllowed = 447 279 | 280 | // When there is an error with TLS certificates 281 | const TLSError = 448 282 | 283 | // Error when interacting with a selector 284 | const SelectorError = 449 285 | 286 | // Used for assert statements 287 | const InvariantFailure = 500 288 | 289 | // Haha lol 290 | const NotImplemented = 501 291 | -------------------------------------------------------------------------------- /core.go: -------------------------------------------------------------------------------- 1 | package btrdb 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "strings" 7 | "sync" 8 | "sync/atomic" 9 | "time" 10 | 11 | "google.golang.org/grpc" 12 | "google.golang.org/grpc/codes" 13 | 14 | pb "github.com/BTrDB/btrdb/v5/v5api" 15 | logging "github.com/op/go-logging" 16 | "github.com/pborman/uuid" 17 | ) 18 | 19 | var lg *logging.Logger 20 | 21 | func init() { 22 | lg = logging.MustGetLogger("log") 23 | } 24 | 25 | //ErrorDisconnected is returned when operations are attempted after Disconnect() 26 | //is called. 27 | var ErrorDisconnected = &CodedError{&pb.Status{Code: 421, Msg: "Driver is disconnected"}} 28 | 29 | //ErrorClusterDegraded is returned when a write operation on an unmapped UUID is attempted. 30 | //generally the same operation will succeed if attempted once the cluster has recovered. 31 | var ErrorClusterDegraded = &CodedError{&pb.Status{Code: 419, Msg: "Cluster is degraded"}} 32 | 33 | //ErrorWrongArgs is returned from API functions if the parameters are nonsensical 34 | var ErrorWrongArgs = &CodedError{&pb.Status{Code: 421, Msg: "Invalid Arguments"}} 35 | 36 | //ErrorNoSuchStream is returned if an operation is attempted on a stream when 37 | //it does not exist. 38 | //var ErrorNoSuchStream = &CodedError{&pb.Status{Code: 404, Msg: "No such stream"}} 39 | 40 | //BTrDB is the main object you should use to interact with BTrDB. 41 | type BTrDB struct { 42 | //This covers the mash 43 | mashwmu sync.Mutex 44 | activeMash atomic.Value 45 | 46 | isproxied bool 47 | 48 | closed bool 49 | 50 | //This covers the epcache 51 | epmu sync.RWMutex 52 | epcache map[uint32]*Endpoint 53 | 54 | bootstraps []string 55 | 56 | apikey string 57 | 58 | //Must hold this when evaluating if an endpoint has failed and 59 | //requires a resync 60 | resyncMu sync.Mutex 61 | //Incremented every time there is a resync 62 | numResyncs int64 63 | } 64 | 65 | func newBTrDB() *BTrDB { 66 | return &BTrDB{epcache: make(map[uint32]*Endpoint)} 67 | } 68 | 69 | //StatPoint represents a statistical summary of a window. The length of that 70 | //window must be determined from context (e.g the parameters passed to AlignedWindow or Window methods) 71 | type StatPoint struct { 72 | //The time of the start of the window, in nanoseconds since the epoch UTC 73 | Time int64 74 | Min float64 75 | Mean float64 76 | Max float64 77 | Count uint64 78 | StdDev float64 79 | } 80 | 81 | //Connect takes a list of endpoints and returns a BTrDB handle. 82 | //Note that only a single endpoint is technically required, but having 83 | //more endpoints will make the initial connection more robust to cluster 84 | //changes. Different addresses for the same endpoint are permitted 85 | func Connect(ctx context.Context, endpoints ...string) (*BTrDB, error) { 86 | return ConnectAuth(ctx, "", endpoints...) 87 | } 88 | 89 | //ConnectAuth takes an API key and a list of endpoints and returns a BTrDB handle. 90 | //Note that only a single endpoint is technically required, but having 91 | //more endpoints will make the initial connection more robust to cluster 92 | //changes. Different addresses for the same endpoint are permitted 93 | func ConnectAuth(ctx context.Context, apikey string, endpoints ...string) (*BTrDB, error) { 94 | if len(endpoints) == 0 { 95 | return nil, fmt.Errorf("No endpoints provided") 96 | } 97 | b := newBTrDB() 98 | b.apikey = apikey 99 | b.bootstraps = endpoints 100 | for _, epa := range endpoints { 101 | ep, err := ConnectEndpointAuth(ctx, apikey, epa) 102 | if ctx.Err() != nil { 103 | return nil, ctx.Err() 104 | } 105 | if err != nil { 106 | lg.Warningf("attempt to connect to %s yielded %v", epa, err) 107 | continue 108 | } 109 | mash, inf, err := ep.Info(ctx) 110 | if err != nil { 111 | lg.Warningf("attempt to obtain MASH from %s yielded %v", epa, err) 112 | ep.Disconnect() 113 | continue 114 | } 115 | if inf.GetProxy() != nil { 116 | //This is a proxied BTrDB cluster 117 | b.isproxied = true 118 | } else { 119 | b.activeMash.Store(mash) 120 | } 121 | ep.Disconnect() 122 | break 123 | } 124 | if !b.isproxied && b.activeMash.Load() == nil { 125 | return nil, fmt.Errorf("Could not connect to cluster via provided endpoints") 126 | } 127 | return b, nil 128 | } 129 | 130 | //Disconnect will close all active connections to the cluster. All future calls 131 | //will return ErrorDisconnected 132 | func (b *BTrDB) Disconnect() error { 133 | b.epmu.Lock() 134 | defer b.epmu.Unlock() 135 | var gerr error 136 | for _, ep := range b.epcache { 137 | err := ep.Disconnect() 138 | if err != nil { 139 | gerr = err 140 | } 141 | } 142 | b.closed = true 143 | return gerr 144 | } 145 | 146 | //EndpointForHash is a low level function that returns a single endpoint for an 147 | //endpoint hash. 148 | func (b *BTrDB) EndpointForHash(ctx context.Context, hash uint32) (*Endpoint, error) { 149 | if ctx.Err() != nil { 150 | return nil, ctx.Err() 151 | } 152 | if b.isproxied { 153 | return b.EndpointFor(ctx, nil) 154 | } 155 | m := b.activeMash.Load().(*MASH) 156 | b.epmu.Lock() 157 | ep, ok := b.epcache[hash] 158 | if ok { 159 | b.epmu.Unlock() 160 | return ep, nil 161 | } 162 | var addrs []string 163 | for _, ep := range m.eps { 164 | if ep.hash == hash { 165 | addrs = ep.grpc 166 | } 167 | } 168 | //We need to connect to endpoint 169 | nep, err := ConnectEndpointAuth(ctx, b.apikey, addrs...) 170 | if err != nil { 171 | b.epmu.Unlock() 172 | return nil, err 173 | } 174 | b.epcache[hash] = nep 175 | b.epmu.Unlock() 176 | return nep, nil 177 | } 178 | 179 | //ReadEndpointFor returns the endpoint that should be used to read the given uuid 180 | func (b *BTrDB) ReadEndpointFor(ctx context.Context, uuid uuid.UUID) (*Endpoint, error) { 181 | //TODO do rpref 182 | return b.EndpointFor(ctx, uuid) 183 | } 184 | 185 | //EndpointFor returns the endpoint that should be used to write the given uuid 186 | func (b *BTrDB) EndpointFor(ctx context.Context, uuid uuid.UUID) (*Endpoint, error) { 187 | if ctx.Err() != nil { 188 | return nil, ctx.Err() 189 | } 190 | if b.isproxied { 191 | b.epmu.Lock() 192 | defer b.epmu.Unlock() 193 | for _, ep := range b.epcache { 194 | return ep, nil 195 | } 196 | //We need to connect to endpoint 197 | nep, err := ConnectEndpointAuth(ctx, b.apikey, b.bootstraps...) 198 | if err != nil { 199 | return nil, err 200 | } 201 | b.epcache[0] = nep 202 | return nep, nil 203 | } 204 | m := b.activeMash.Load().(*MASH) 205 | ok, hash, addrs := m.EndpointFor(uuid) 206 | if !ok { 207 | b.ResyncMash() 208 | return nil, ErrorClusterDegraded 209 | } 210 | b.epmu.Lock() 211 | ep, ok := b.epcache[hash] 212 | if ok { 213 | b.epmu.Unlock() 214 | return ep, nil 215 | } 216 | //We need to connect to endpoint 217 | nep, err := ConnectEndpointAuth(ctx, b.apikey, addrs...) //XX 218 | if err != nil { 219 | b.epmu.Unlock() 220 | return nil, err 221 | } 222 | b.epcache[hash] = nep 223 | b.epmu.Unlock() 224 | return nep, nil 225 | } 226 | 227 | func (b *BTrDB) dropEpcache() { 228 | for _, e := range b.epcache { 229 | e.Disconnect() 230 | } 231 | b.epcache = make(map[uint32]*Endpoint) 232 | } 233 | 234 | func (b *BTrDB) GetAnyEndpoint(ctx context.Context) (*Endpoint, error) { 235 | b.epmu.RLock() 236 | for _, ep := range b.epcache { 237 | b.epmu.RUnlock() 238 | return ep, nil 239 | } 240 | b.epmu.RUnlock() 241 | //Nothing in cache 242 | return b.EndpointFor(ctx, uuid.NewRandom()) 243 | } 244 | 245 | func (b *BTrDB) ResyncMash() { 246 | if b.isproxied { 247 | b.resyncProxied() 248 | } else { 249 | b.resyncInternalMash() 250 | } 251 | } 252 | func (b *BTrDB) resyncProxied() { 253 | b.epmu.Lock() 254 | defer b.epmu.Unlock() 255 | b.dropEpcache() 256 | ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) 257 | ep, err := ConnectEndpointAuth(ctx, b.apikey, b.bootstraps...) 258 | cancel() 259 | if err != nil { 260 | return 261 | } 262 | b.epcache[0] = ep 263 | return 264 | } 265 | func (b *BTrDB) resyncInternalMash() { 266 | b.epmu.Lock() 267 | 268 | for _, ep := range b.epcache { 269 | ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) 270 | mash, _, err := ep.Info(ctx) 271 | cancel() 272 | if err == nil { 273 | b.activeMash.Store(mash) 274 | b.dropEpcache() 275 | b.epmu.Unlock() 276 | return 277 | } else { 278 | lg.Warningf("attempt to obtain info from endpoint cache error: %v", err) 279 | } 280 | } 281 | 282 | //Try bootstraps 283 | for _, epa := range b.bootstraps { 284 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 285 | ep, err := ConnectEndpointAuth(ctx, b.apikey, epa) 286 | cancel() 287 | if err != nil { 288 | lg.Warningf("attempt to connect to %s yielded %v", epa, err) 289 | continue 290 | } 291 | ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) 292 | mash, _, err := ep.Info(ctx) 293 | cancel() 294 | if err != nil { 295 | ep.Disconnect() 296 | lg.Warningf("attempt to obtain MASH from %s yielded %v", epa, err) 297 | continue 298 | } 299 | b.activeMash.Store(mash) 300 | b.dropEpcache() 301 | ep.Disconnect() 302 | b.epmu.Unlock() 303 | return 304 | } 305 | b.epmu.Unlock() 306 | //Try clients already in the MASH 307 | cm := b.activeMash.Load().(*MASH) 308 | for _, mbr := range cm.Members { 309 | if !mbr.In { 310 | continue 311 | } 312 | ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) 313 | ep, err := b.EndpointForHash(ctx, mbr.Hash) 314 | if err != nil { 315 | lg.Warningf("obtaining endpoint for hash error: %v", err) 316 | cancel() 317 | continue 318 | } 319 | mash, _, err := ep.Info(ctx) 320 | cancel() 321 | if err == nil { 322 | b.activeMash.Store(mash) 323 | b.dropEpcache() 324 | return 325 | } else { 326 | lg.Warningf("obtaining endpoint info error: %v", err) 327 | } 328 | } 329 | lg.Warningf("failed to resync MASH, is BTrDB unavailable?") 330 | } 331 | 332 | //This returns true if you should redo your operation (and get new ep) 333 | //and false if you should return the last value/error you got 334 | func (b *BTrDB) TestEpError(ep *Endpoint, err error) bool { 335 | startNumResyncs := atomic.LoadInt64(&b.numResyncs) 336 | if ep == nil && err == nil { 337 | return true 338 | } 339 | if err == forceEp { 340 | return true 341 | } 342 | if err == nil { 343 | return false 344 | } 345 | 346 | mustResync := false 347 | 348 | if strings.Contains(err.Error(), "getsockopt: connection refused") { 349 | mustResync = true 350 | //why grpc no use proper code :( 351 | lg.Warningf("Got conn refused, resyncing silently") 352 | } else if strings.Contains(err.Error(), "Endpoint is unreachable on all addresses") { 353 | mustResync = true 354 | lg.Warningf("Got conn refused, resyncing silently") 355 | } else if grpc.Code(err) == codes.Unavailable { 356 | mustResync = true 357 | lg.Warningf("Got unavailable, resyncing mash silently") 358 | } else { 359 | ce := ToCodedError(err) 360 | if ce.Code == 405 { 361 | mustResync = true 362 | lg.Warningf("Got 405 (wrong endpoint) silently retrying") 363 | } 364 | if ce.Code == 419 { 365 | mustResync = true 366 | lg.Warningf("Got 419 (cluster degraded) silently retrying") 367 | } 368 | } 369 | 370 | if mustResync { 371 | //This is to avoid tight resync loops 372 | time.Sleep(300 * time.Millisecond) 373 | b.resyncMu.Lock() 374 | //No other goroutine has done a resync since we started this testEpError 375 | if b.numResyncs == startNumResyncs { 376 | b.ResyncMash() 377 | b.numResyncs++ 378 | } 379 | b.resyncMu.Unlock() 380 | return true 381 | } 382 | return false 383 | } 384 | 385 | //This should invalidate the endpoint if some kind of error occurs. 386 | //Because some values may have already been delivered, async functions using 387 | //snoopEpErr will not be able to mask cluster errors from the user 388 | func (b *BTrDB) SnoopEpErr(ep *Endpoint, err chan error) chan error { 389 | rv := make(chan error, 2) 390 | go func() { 391 | for e := range err { 392 | //if e is special invalidate ep 393 | b.TestEpError(ep, e) 394 | rv <- e 395 | } 396 | close(rv) 397 | }() 398 | return rv 399 | } 400 | 401 | //Subscriptions represent a set of 402 | //real time subscriptions to streaming data. 403 | type Subscriptions struct { 404 | err chan error 405 | id []uuid.UUID 406 | c chan SubRecord 407 | } 408 | 409 | //Data for a single stream returned from a Subscription. 410 | type SubRecord struct { 411 | ID uuid.UUID 412 | Val []RawPoint 413 | } 414 | 415 | //An endpoint and its associated uuids. 416 | type EPGroup struct { 417 | *Endpoint 418 | ID []uuid.UUID 419 | } 420 | 421 | //EndpointSplit takes a variadic list of uuids and organizes them by the endpoint 422 | //responsible for them. 423 | func (b *BTrDB) EndpointsSplit(ctx context.Context, id ...uuid.UUID) ([]EPGroup, error) { 424 | var err error 425 | var ep *Endpoint 426 | who := make(map[string][]uuid.UUID) 427 | for b.TestEpError(ep, err) { 428 | ep, err = b.GetAnyEndpoint(ctx) 429 | if err != nil { 430 | continue 431 | } 432 | if b.isproxied { 433 | who["proxy"] = id 434 | } else { 435 | m := b.activeMash.Load().(*MASH) 436 | for i := range id { 437 | _, _, addrs := m.EndpointFor(id[i]) 438 | if addrs == nil || len(addrs) != 1 { 439 | return nil, fmt.Errorf("can't find endpoint for %s", id[i]) 440 | } 441 | who[addrs[0]] = append(who[addrs[0]], id[i]) 442 | 443 | } 444 | } 445 | } 446 | 447 | var out []EPGroup 448 | i := 0 449 | for _, v := range who { 450 | ep, err := b.EndpointFor(ctx, v[0]) 451 | for b.TestEpError(ep, err) { 452 | ep, err = b.EndpointFor(ctx, v[0]) 453 | } 454 | if err != nil { 455 | return nil, err 456 | } 457 | out = append(out, EPGroup{ep, v}) 458 | i++ 459 | } 460 | return out, nil 461 | } 462 | 463 | //Subscribe takes a list of stream UUIDs to receive real time data points from. 464 | //Connections are made to each relevant endpoints, and streams that belong to the 465 | //same endpoint use the same connection. Data points are "raw", meaning they 466 | //are given in the exact same sequence the database received them from the client. 467 | func (b *BTrDB) Subscribe(ctx context.Context, id ...uuid.UUID) (*Subscriptions, error) { 468 | if len(id) == 0 { 469 | return nil, fmt.Errorf("no ids provided") 470 | } 471 | subs := &Subscriptions{ 472 | id: id, 473 | err: make(chan error), 474 | c: make(chan SubRecord), 475 | } 476 | 477 | eps, err := b.EndpointsSplit(ctx, id...) 478 | if err != nil { 479 | return nil, err 480 | } 481 | for _, ep := range eps { 482 | ep.Endpoint.SubscribeTo(ctx, ep.ID, subs.c, subs.err) 483 | } 484 | return subs, nil 485 | } 486 | 487 | //Next gives either the most recent data for the set of subscriptions 488 | //or an error regarding the connection state. 489 | func (subs *Subscriptions) Next(ctx context.Context) (sr SubRecord, err error) { 490 | select { 491 | case <-ctx.Done(): 492 | err = ctx.Err() 493 | case err = <-subs.err: 494 | case sr = <-subs.c: 495 | } 496 | return 497 | } 498 | -------------------------------------------------------------------------------- /driver.go: -------------------------------------------------------------------------------- 1 | package btrdb 2 | 3 | //don't automatically go:generate protoc -I/usr/local/include -I. -Igrpc-gateway/third_party/googleapis --swagger_out=logtostderr=true:. ./v5api/btrdb.proto 4 | import ( 5 | "context" 6 | "crypto/tls" 7 | "encoding/json" 8 | "errors" 9 | "fmt" 10 | "io" 11 | "os" 12 | "strings" 13 | "time" 14 | 15 | "github.com/BTrDB/btrdb/v5/bte" 16 | pb "github.com/BTrDB/btrdb/v5/v5api" 17 | "github.com/pborman/uuid" 18 | "google.golang.org/grpc" 19 | "google.golang.org/grpc/credentials" 20 | ) 21 | 22 | //PropertyVersion is the version of a stream annotations and tags. It begins at 1 23 | //for a newly created stream and increases by 1 for each SetStreamAnnotation 24 | //or SetStreamTags call. An PropertyVersion of 0 means "any version" 25 | type PropertyVersion uint64 26 | 27 | //How long we try to connect to an endpoint before trying the next one 28 | const EndpointTimeout = 5 * time.Second 29 | 30 | //Endpoint is a low level connection to a single server. Rather use 31 | //BTrDB which manages creating and destroying Endpoint objects as required 32 | type Endpoint struct { 33 | g pb.BTrDBClient 34 | conn *grpc.ClientConn 35 | } 36 | 37 | //RawPoint represents a single timestamped value 38 | type RawPoint struct { 39 | //Nanoseconds since the epoch 40 | Time int64 41 | //Value. Units are stream-dependent 42 | Value float64 43 | } 44 | 45 | //RawPoint represents a single timestamped value 46 | type RawPointVec struct { 47 | //Nanoseconds since the epoch 48 | Time int64 49 | //Value. Units are stream-dependent 50 | Value []float64 51 | } 52 | 53 | type InsertParams struct { 54 | RoundBits *int 55 | MergePolicy MergePolicy 56 | } 57 | 58 | type MergePolicy = int 59 | 60 | const ( 61 | MPNever = MergePolicy(iota) 62 | MPEqual 63 | MPRetain 64 | MPReplace 65 | ) 66 | 67 | var forceEp = errors.New("Not really an error, you should not see this") 68 | 69 | type apikeyCred string 70 | 71 | func (a apikeyCred) GetRequestMetadata(ctx context.Context, uris ...string) (map[string]string, error) { 72 | return map[string]string{ 73 | "authorization": fmt.Sprintf("bearer %s", a), 74 | }, nil 75 | } 76 | 77 | func (a apikeyCred) RequireTransportSecurity() bool { 78 | return false 79 | } 80 | 81 | //ConnectEndpoint is a low level call that connects to a single BTrDB 82 | //server. It takes multiple arguments, but it is assumed that they are 83 | //all different addresses for the same server, in decreasing order of 84 | //priority. It returns a Endpoint, which is generally never used directly. 85 | //Rather use Connect() 86 | func ConnectEndpoint(ctx context.Context, addresses ...string) (*Endpoint, error) { 87 | return ConnectEndpointAuth(ctx, "", addresses...) 88 | } 89 | 90 | //ConnectEndpointAuth is a low level call that connects to a single BTrDB 91 | //server. It takes multiple arguments, but it is assumed that they are 92 | //all different addresses for the same server, in decreasing order of 93 | //priority. It returns a Endpoint, which is generally never used directly. 94 | //Rather use ConnectAuthenticated() 95 | func ConnectEndpointAuth(ctx context.Context, apikey string, addresses ...string) (*Endpoint, error) { 96 | if len(addresses) == 0 { 97 | return nil, fmt.Errorf("No addresses provided") 98 | } 99 | ep_errors := "" 100 | for _, a := range addresses { 101 | if ctx.Err() != nil { 102 | return nil, ctx.Err() 103 | } 104 | dl, ok := ctx.Deadline() 105 | var tmt time.Duration 106 | if ok { 107 | tmt = dl.Sub(time.Now()) 108 | if tmt > EndpointTimeout { 109 | tmt = EndpointTimeout 110 | } 111 | } else { 112 | tmt = EndpointTimeout 113 | } 114 | addrport := strings.SplitN(a, ":", 2) 115 | if len(addrport) != 2 { 116 | fmt.Printf("invalid address:port %q\n", a) 117 | continue 118 | } 119 | secure := false 120 | 121 | switch { 122 | case os.Getenv("BTRDB_FORCE_SECURE") == "YES": 123 | secure = true 124 | case addrport[1] == "4411" && os.Getenv("BTRDB_FORCE_INSECURE") != "YES": 125 | secure = true 126 | default: 127 | secure = false 128 | } 129 | 130 | dc := grpc.NewGZIPDecompressor() 131 | dialopts := []grpc.DialOption{ 132 | grpc.WithTimeout(tmt), 133 | grpc.FailOnNonTempDialError(true), 134 | grpc.WithBlock(), 135 | grpc.WithDecompressor(dc), 136 | grpc.WithInitialWindowSize(1 * 1024 * 1024), 137 | grpc.WithInitialConnWindowSize(1 * 1024 * 1024)} 138 | 139 | if secure { 140 | dialopts = append(dialopts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))) 141 | } else { 142 | dialopts = append(dialopts, grpc.WithInsecure()) 143 | } 144 | if apikey != "" { 145 | dialopts = append(dialopts, grpc.WithPerRPCCredentials(apikeyCred(apikey))) 146 | } 147 | conn, err := grpc.Dial(a, dialopts...) 148 | if err != nil { 149 | if ctx.Err() != nil { 150 | return nil, ctx.Err() 151 | } 152 | ep_errors += fmt.Sprintf("endpoint error: err=%v a=%v\n", err, a) 153 | continue 154 | } 155 | client := pb.NewBTrDBClient(conn) 156 | inf, err := client.Info(ctx, &pb.InfoParams{}) 157 | if err != nil { 158 | ep_errors += fmt.Sprintf("endpoint error: err=%v a=%v\n", err, a) 159 | continue 160 | } 161 | if inf.MajorVersion != 5 { 162 | lg.Errorf("BTrDB server is the wrong version (expecting v5.x, got v%d.%d)", inf.MajorVersion, inf.MinorVersion) 163 | return nil, fmt.Errorf("Endpoint is the wrong version") 164 | } 165 | rv := &Endpoint{g: client, conn: conn} 166 | return rv, nil 167 | } 168 | fmt.Printf(ep_errors) 169 | 170 | return nil, fmt.Errorf("Endpoint is unreachable on all addresses") 171 | } 172 | 173 | //GetGRPC will return the underlying GRPC client object. 174 | func (b *Endpoint) GetGRPC() pb.BTrDBClient { 175 | return b.g 176 | } 177 | 178 | func (b *Endpoint) GetClientConnection() *grpc.ClientConn { 179 | return b.conn 180 | } 181 | 182 | //Disconnect will close the underlying GRPC connection. The endpoint cannot be used 183 | //after calling this method. 184 | func (b *Endpoint) Disconnect() error { 185 | return b.conn.Close() 186 | } 187 | 188 | func (b *Endpoint) InsertGeneric(ctx context.Context, uu uuid.UUID, values []*pb.RawPoint, p *InsertParams) error { 189 | policy := pb.MergePolicy_NEVER 190 | rounding := (*pb.RoundSpec)(nil) 191 | if p != nil { 192 | if p.RoundBits != nil { 193 | rounding = &pb.RoundSpec{ 194 | Spec: &pb.RoundSpec_Bits{Bits: int32(*p.RoundBits)}, 195 | } 196 | } 197 | switch p.MergePolicy { 198 | case MPNever: 199 | policy = pb.MergePolicy_NEVER 200 | case MPEqual: 201 | policy = pb.MergePolicy_EQUAL 202 | case MPRetain: 203 | policy = pb.MergePolicy_RETAIN 204 | case MPReplace: 205 | policy = pb.MergePolicy_REPLACE 206 | } 207 | } 208 | rv, err := b.g.Insert(ctx, &pb.InsertParams{ 209 | Uuid: uu, 210 | Sync: false, 211 | Values: values, 212 | MergePolicy: policy, 213 | Rounding: rounding, 214 | }) 215 | if err != nil { 216 | return err 217 | } 218 | if rv.GetStat() != nil { 219 | return &CodedError{rv.GetStat()} 220 | } 221 | return nil 222 | } 223 | 224 | func (b *Endpoint) InsertUnique(ctx context.Context, uu uuid.UUID, values []*pb.RawPoint, mp MergePolicy) error { 225 | return b.InsertGeneric(ctx, uu, values, &InsertParams{MergePolicy: mp}) 226 | } 227 | 228 | //Insert is a low level function, rather use Stream.Insert() 229 | func (b *Endpoint) Insert(ctx context.Context, uu uuid.UUID, values []*pb.RawPoint, p *InsertParams) error { 230 | return b.InsertGeneric(ctx, uu, values, p) 231 | } 232 | 233 | //FaultInject is a debugging function that allows specific low level control of the endpoint. 234 | //If you have to read the documentation, this is not for you. Server must be started with 235 | //$BTRDB_ENABLE_FAULT_INJECT=YES 236 | func (b *Endpoint) FaultInject(ctx context.Context, typ uint64, args []byte) ([]byte, error) { 237 | rv, err := b.g.FaultInject(ctx, &pb.FaultInjectParams{ 238 | Type: typ, 239 | Params: args, 240 | }) 241 | if err != nil { 242 | return nil, err 243 | } 244 | if rv.GetStat() != nil { 245 | return nil, &CodedError{rv.GetStat()} 246 | } 247 | return rv.Rv, nil 248 | } 249 | 250 | //Create is a low level function, rather use BTrDB.Create() 251 | func (b *Endpoint) Create(ctx context.Context, uu uuid.UUID, collection string, tags map[string]*string, annotations map[string]*string) error { 252 | taglist := []*pb.KeyOptValue{} 253 | for k, v := range tags { 254 | if v == nil { 255 | taglist = append(taglist, &pb.KeyOptValue{Key: k}) 256 | } else { 257 | taglist = append(taglist, &pb.KeyOptValue{Key: k, Val: &pb.OptValue{Value: *v}}) 258 | } 259 | } 260 | annlist := []*pb.KeyOptValue{} 261 | for k, v := range annotations { 262 | if v == nil { 263 | annlist = append(annlist, &pb.KeyOptValue{Key: k}) 264 | } else { 265 | annlist = append(annlist, &pb.KeyOptValue{Key: k, Val: &pb.OptValue{Value: *v}}) 266 | } 267 | } 268 | rv, err := b.g.Create(ctx, &pb.CreateParams{ 269 | Uuid: uu, 270 | Collection: collection, 271 | Tags: taglist, 272 | Annotations: annlist, 273 | }) 274 | if err != nil { 275 | return err 276 | } 277 | if rv.GetStat() != nil { 278 | return &CodedError{rv.GetStat()} 279 | } 280 | return nil 281 | } 282 | 283 | //ListAllCollections is a low level function, and in particular will only work 284 | //with small numbers of collections. Rather use BTrDB.ListAllCollections() 285 | func (b *Endpoint) ListAllCollections(ctx context.Context) (chan string, chan error) { 286 | return b.ListCollections(ctx, "") 287 | } 288 | 289 | //StreamInfo is a low level function, rather use Stream.Annotation() 290 | func (b *Endpoint) StreamInfo(ctx context.Context, uu uuid.UUID, omitDescriptor bool, omitVersion bool) ( 291 | collection string, 292 | pver PropertyVersion, 293 | tags map[string]*string, 294 | anns map[string]*string, 295 | version uint64, err error) { 296 | rv, err := b.g.StreamInfo(ctx, &pb.StreamInfoParams{ 297 | Uuid: uu, 298 | OmitDescriptor: omitDescriptor, 299 | OmitVersion: omitVersion}) 300 | if err != nil { 301 | return "", 0, nil, nil, 0, err 302 | } 303 | if rv.GetStat() != nil { 304 | return "", 0, nil, nil, 0, &CodedError{rv.GetStat()} 305 | } 306 | if !omitDescriptor { 307 | tags = make(map[string]*string) 308 | for _, kv := range rv.Descriptor_.Tags { 309 | if kv.Val == nil { 310 | tags[kv.Key] = nil 311 | } else { 312 | vc := kv.Val.Value 313 | tags[kv.Key] = &vc 314 | } 315 | } 316 | anns = make(map[string]*string) 317 | for _, kv := range rv.Descriptor_.Annotations { 318 | if kv.Val == nil { 319 | anns[kv.Key] = nil 320 | } else { 321 | vc := kv.Val.Value 322 | anns[kv.Key] = &vc 323 | } 324 | } 325 | pver = PropertyVersion(rv.Descriptor_.PropertyVersion) 326 | collection = rv.Descriptor_.Collection 327 | } 328 | return collection, pver, tags, anns, rv.VersionMajor, nil 329 | } 330 | 331 | //SetStreamAnnotation is a low level function, rather use Stream.SetAnnotation() or Stream.CompareAndSetAnnotation() 332 | func (b *Endpoint) SetStreamAnnotations(ctx context.Context, uu uuid.UUID, expected PropertyVersion, changes map[string]*string, remove []string) error { 333 | ch := []*pb.KeyOptValue{} 334 | for k, v := range changes { 335 | kop := &pb.KeyOptValue{ 336 | Key: k, 337 | } 338 | if v != nil { 339 | kop.Val = &pb.OptValue{Value: *v} 340 | } 341 | ch = append(ch, kop) 342 | } 343 | rv, err := b.g.SetStreamAnnotations(ctx, &pb.SetStreamAnnotationsParams{Uuid: uu, ExpectedPropertyVersion: uint64(expected), Changes: ch, Removals: remove}) 344 | if err != nil { 345 | return err 346 | } 347 | if rv.GetStat() != nil { 348 | return &CodedError{rv.GetStat()} 349 | } 350 | return nil 351 | } 352 | 353 | //SetStreamTags is a low level function, rather use Stream.SetTags() 354 | func (b *Endpoint) SetStreamTags(ctx context.Context, uu uuid.UUID, expected PropertyVersion, collection string, changes map[string]*string) error { 355 | ch := []*pb.KeyOptValue{} 356 | for k, v := range changes { 357 | if v == nil { 358 | ch = append(ch, &pb.KeyOptValue{Key: k}) 359 | } else { 360 | ch = append(ch, &pb.KeyOptValue{Key: k, Val: &pb.OptValue{Value: *v}}) 361 | } 362 | } 363 | rv, err := b.g.SetStreamTags(ctx, &pb.SetStreamTagsParams{Uuid: uu, ExpectedPropertyVersion: uint64(expected), Tags: ch, Collection: collection}) 364 | if err != nil { 365 | return err 366 | } 367 | if rv.GetStat() != nil { 368 | return &CodedError{rv.GetStat()} 369 | } 370 | return nil 371 | } 372 | 373 | //GetMetadataUsage is a low level function. Rather use BTrDB.GetMetadataUsage 374 | func (b *Endpoint) GetMetadataUsage(ctx context.Context, prefix string) (tags map[string]int, annotations map[string]int, err error) { 375 | rv, err := b.g.GetMetadataUsage(ctx, &pb.MetadataUsageParams{ 376 | Prefix: prefix, 377 | }) 378 | if err != nil { 379 | return nil, nil, err 380 | } 381 | if rv.Stat != nil { 382 | return nil, nil, &CodedError{rv.GetStat()} 383 | } 384 | tags = make(map[string]int) 385 | annotations = make(map[string]int) 386 | for _, kv := range rv.Tags { 387 | tags[kv.Key] = int(kv.Count) 388 | } 389 | for _, kv := range rv.Annotations { 390 | annotations[kv.Key] = int(kv.Count) 391 | } 392 | return tags, annotations, nil 393 | } 394 | 395 | //ListCollections is a low level function, and in particular has complex constraints. Rather use BTrDB.ListCollections() 396 | func (b *Endpoint) ListCollections(ctx context.Context, prefix string) (chan string, chan error) { 397 | rv, err := b.g.ListCollections(ctx, &pb.ListCollectionsParams{ 398 | Prefix: prefix, 399 | }) 400 | rvc := make(chan string, 100) 401 | rve := make(chan error, 1) 402 | if err != nil { 403 | close(rvc) 404 | rve <- err 405 | close(rve) 406 | return rvc, rve 407 | } 408 | go func() { 409 | for { 410 | cols, err := rv.Recv() 411 | if err == io.EOF { 412 | close(rvc) 413 | close(rve) 414 | return 415 | } 416 | if err != nil { 417 | close(rvc) 418 | rve <- err 419 | close(rve) 420 | return 421 | } 422 | if cols.Stat != nil { 423 | close(rvc) 424 | rve <- &CodedError{cols.Stat} 425 | close(rve) 426 | return 427 | } 428 | for _, r := range cols.Collections { 429 | rvc <- r 430 | } 431 | } 432 | }() 433 | return rvc, rve 434 | } 435 | 436 | func streamFromLookupResult(lr *pb.StreamDescriptor, b *BTrDB) *Stream { 437 | rv := &Stream{ 438 | uuid: lr.Uuid, 439 | hasTags: true, 440 | tags: make(map[string]*string), 441 | hasAnnotation: true, 442 | annotations: make(map[string]*string), 443 | propertyVersion: PropertyVersion(lr.PropertyVersion), 444 | hasCollection: true, 445 | collection: lr.Collection, 446 | b: b, 447 | } 448 | for _, kv := range lr.Tags { 449 | if kv.Val == nil { 450 | rv.tags[kv.Key] = nil 451 | } else { 452 | vc := kv.Val.Value 453 | rv.tags[kv.Key] = &vc 454 | } 455 | } 456 | for _, kv := range lr.Annotations { 457 | if kv.Val == nil { 458 | rv.annotations[kv.Key] = nil 459 | } else { 460 | vc := kv.Val.Value 461 | rv.annotations[kv.Key] = &vc 462 | } 463 | } 464 | return rv 465 | } 466 | 467 | //LookupStreams is a low level function, rather use BTrDB.LookupStreams() 468 | func (b *Endpoint) LookupStreams(ctx context.Context, collection string, isCollectionPrefix bool, tags map[string]*string, annotations map[string]*string, patchDB *BTrDB) (chan *Stream, chan error) { 469 | ltags := []*pb.KeyOptValue{} 470 | for k, v := range tags { 471 | kop := &pb.KeyOptValue{ 472 | Key: k, 473 | } 474 | if v != nil { 475 | kop.Val = &pb.OptValue{Value: *v} 476 | } 477 | ltags = append(ltags, kop) 478 | } 479 | lanns := []*pb.KeyOptValue{} 480 | for k, v := range annotations { 481 | kop := &pb.KeyOptValue{ 482 | Key: k, 483 | } 484 | if v != nil { 485 | kop.Val = &pb.OptValue{Value: *v} 486 | } 487 | lanns = append(lanns, kop) 488 | } 489 | params := &pb.LookupStreamsParams{ 490 | Collection: collection, 491 | IsCollectionPrefix: isCollectionPrefix, 492 | Tags: ltags, 493 | Annotations: lanns, 494 | } 495 | rv, err := b.g.LookupStreams(ctx, params) 496 | rvc := make(chan *Stream, 100) 497 | rve := make(chan error, 1) 498 | if err != nil { 499 | close(rvc) 500 | rve <- err 501 | close(rve) 502 | return rvc, rve 503 | } 504 | go func() { 505 | for { 506 | lr, err := rv.Recv() 507 | if err == io.EOF { 508 | close(rvc) 509 | close(rve) 510 | return 511 | } 512 | if err != nil { 513 | close(rvc) 514 | rve <- err 515 | close(rve) 516 | return 517 | } 518 | if lr.Stat != nil { 519 | close(rvc) 520 | rve <- &CodedError{lr.Stat} 521 | close(rve) 522 | return 523 | } 524 | for _, r := range lr.Results { 525 | rvc <- streamFromLookupResult(r, patchDB) 526 | } 527 | } 528 | }() 529 | return rvc, rve 530 | } 531 | 532 | //SQLQuery is a low level function, rather use BTrDB.SQLQuery() 533 | func (b *Endpoint) SQLQuery(ctx context.Context, query string, params []string) (chan map[string]interface{}, chan error) { 534 | rv, err := b.g.SQLQuery(ctx, &pb.SQLQueryParams{ 535 | Query: query, 536 | Params: params, 537 | }) 538 | rvc := make(chan map[string]interface{}, 100) 539 | rve := make(chan error, 1) 540 | if err != nil { 541 | close(rvc) 542 | rve <- err 543 | close(rve) 544 | return rvc, rve 545 | } 546 | go func() { 547 | for { 548 | row, err := rv.Recv() 549 | if err == io.EOF { 550 | close(rvc) 551 | close(rve) 552 | return 553 | } 554 | if err != nil { 555 | close(rvc) 556 | rve <- err 557 | close(rve) 558 | return 559 | } 560 | if row.Stat != nil { 561 | close(rvc) 562 | rve <- &CodedError{row.Stat} 563 | close(rve) 564 | return 565 | } 566 | for _, r := range row.SQLQueryRow { 567 | m := make(map[string]interface{}) 568 | err := json.Unmarshal(r, &m) 569 | if err != nil { 570 | close(rvc) 571 | rve <- &CodedError{&pb.Status{Code: bte.BadSQLValue, Msg: "could not unmarshal SQL row"}} 572 | close(rve) 573 | return 574 | } 575 | rvc <- m 576 | } 577 | } 578 | }() 579 | return rvc, rve 580 | } 581 | 582 | func (b *Endpoint) MultiRawValues(ctx context.Context, ids []uuid.UUID, 583 | rvc chan RawPointVec, rvv chan uint64, rve chan error, 584 | start, end int64, vers uint64, period int64) { 585 | 586 | idbytes := [][]byte{} 587 | for _, uu := range ids { 588 | idbytes = append(idbytes, uu) 589 | } 590 | rv, err := b.g.MultiRawValues(ctx, &pb.MultiRawValuesParams{ 591 | Uuid: idbytes, 592 | Start: start, 593 | End: end, 594 | VersionMajor: vers, 595 | PeriodNs: period, 596 | }) 597 | wroteVer := false 598 | if err != nil { 599 | close(rvv) 600 | close(rvc) 601 | rve <- err 602 | close(rve) 603 | return 604 | } 605 | go func() { 606 | for { 607 | rawv, err := rv.Recv() 608 | if err == io.EOF { 609 | close(rvc) 610 | close(rvv) 611 | close(rve) 612 | return 613 | } 614 | if err != nil { 615 | close(rvc) 616 | close(rvv) 617 | rve <- err 618 | close(rve) 619 | return 620 | } 621 | if rawv.Stat != nil { 622 | close(rvc) 623 | close(rvv) 624 | rve <- &CodedError{rawv.Stat} 625 | close(rve) 626 | return 627 | } 628 | if !wroteVer { 629 | rvv <- 0 630 | wroteVer = true 631 | } 632 | for _, x := range rawv.Values { 633 | rvc <- RawPointVec{x.Time, x.Value} 634 | } 635 | } 636 | }() 637 | } 638 | 639 | //RawValues is a low level function, rather use Stream.RawValues() 640 | func (b *Endpoint) RawValues(ctx context.Context, uu uuid.UUID, start int64, end int64, version uint64) (chan RawPoint, chan uint64, chan error) { 641 | rv, err := b.g.RawValues(ctx, &pb.RawValuesParams{ 642 | Uuid: uu, 643 | Start: start, 644 | End: end, 645 | VersionMajor: version, 646 | }) 647 | rvc := make(chan RawPoint, 100) 648 | rvv := make(chan uint64, 1) 649 | rve := make(chan error, 1) 650 | wroteVer := false 651 | if err != nil { 652 | close(rvv) 653 | close(rvc) 654 | rve <- err 655 | close(rve) 656 | return rvc, rvv, rve 657 | } 658 | go func() { 659 | for { 660 | rawv, err := rv.Recv() 661 | if err == io.EOF { 662 | close(rvc) 663 | close(rvv) 664 | close(rve) 665 | return 666 | } 667 | if err != nil { 668 | close(rvc) 669 | close(rvv) 670 | rve <- err 671 | close(rve) 672 | return 673 | } 674 | if rawv.Stat != nil { 675 | close(rvc) 676 | close(rvv) 677 | rve <- &CodedError{rawv.Stat} 678 | close(rve) 679 | return 680 | } 681 | if !wroteVer { 682 | rvv <- rawv.VersionMajor 683 | wroteVer = true 684 | } 685 | for _, x := range rawv.Values { 686 | rvc <- RawPoint{x.Time, x.Value} 687 | } 688 | } 689 | }() 690 | return rvc, rvv, rve 691 | } 692 | 693 | //AlignedWindows is a low level function, rather use Stream.AlignedWindows() 694 | func (b *Endpoint) AlignedWindows(ctx context.Context, uu uuid.UUID, start int64, end int64, pointwidth uint8, version uint64) (chan StatPoint, chan uint64, chan error) { 695 | rv, err := b.g.AlignedWindows(ctx, &pb.AlignedWindowsParams{ 696 | Uuid: uu, 697 | Start: start, 698 | End: end, 699 | PointWidth: uint32(pointwidth), 700 | VersionMajor: version, 701 | }) 702 | rvc := make(chan StatPoint, 100) 703 | rvv := make(chan uint64, 1) 704 | rve := make(chan error, 1) 705 | wroteVer := false 706 | if err != nil { 707 | close(rvc) 708 | close(rvv) 709 | rve <- err 710 | close(rve) 711 | return rvc, rvv, rve 712 | } 713 | go func() { 714 | for { 715 | rawv, err := rv.Recv() 716 | if err == io.EOF { 717 | close(rvc) 718 | close(rvv) 719 | close(rve) 720 | return 721 | } 722 | if err != nil { 723 | close(rvc) 724 | close(rvv) 725 | rve <- err 726 | close(rve) 727 | return 728 | } 729 | if rawv.Stat != nil { 730 | close(rvc) 731 | close(rvv) 732 | rve <- &CodedError{rawv.Stat} 733 | close(rve) 734 | return 735 | } 736 | if !wroteVer { 737 | rvv <- rawv.VersionMajor 738 | wroteVer = true 739 | } 740 | for _, x := range rawv.Values { 741 | rvc <- StatPoint{ 742 | Time: x.Time, 743 | Min: x.Min, 744 | Mean: x.Mean, 745 | Max: x.Max, 746 | Count: x.Count, 747 | StdDev: x.Stddev, 748 | } 749 | } 750 | } 751 | }() 752 | return rvc, rvv, rve 753 | } 754 | 755 | //Windows is a low level function, rather use Stream.Windows() 756 | func (b *Endpoint) Windows(ctx context.Context, uu uuid.UUID, start int64, end int64, width uint64, depth uint8, version uint64) (chan StatPoint, chan uint64, chan error) { 757 | rv, err := b.g.Windows(ctx, &pb.WindowsParams{ 758 | Uuid: uu, 759 | Start: start, 760 | End: end, 761 | Width: width, 762 | Depth: uint32(depth), 763 | VersionMajor: version, 764 | }) 765 | rvc := make(chan StatPoint, 100) 766 | rvv := make(chan uint64, 1) 767 | rve := make(chan error, 1) 768 | wroteVer := false 769 | if err != nil { 770 | close(rvc) 771 | close(rvv) 772 | rve <- err 773 | close(rve) 774 | return rvc, rvv, rve 775 | } 776 | go func() { 777 | for { 778 | rawv, err := rv.Recv() 779 | if err == io.EOF { 780 | close(rvc) 781 | close(rvv) 782 | close(rve) 783 | return 784 | } 785 | if err != nil { 786 | close(rvc) 787 | close(rvv) 788 | rve <- err 789 | close(rve) 790 | return 791 | } 792 | if rawv.Stat != nil { 793 | close(rvc) 794 | close(rvv) 795 | rve <- &CodedError{rawv.Stat} 796 | close(rve) 797 | return 798 | } 799 | if !wroteVer { 800 | rvv <- rawv.VersionMajor 801 | wroteVer = true 802 | } 803 | for _, x := range rawv.Values { 804 | rvc <- StatPoint{ 805 | Time: x.Time, 806 | Min: x.Min, 807 | Mean: x.Mean, 808 | Max: x.Max, 809 | Count: x.Count, 810 | StdDev: x.Stddev, 811 | } 812 | } 813 | } 814 | }() 815 | return rvc, rvv, rve 816 | } 817 | 818 | //DeleteRange is a low level function, rather use Stream.DeleteRange() 819 | func (b *Endpoint) DeleteRange(ctx context.Context, uu uuid.UUID, start int64, end int64) (uint64, error) { 820 | rv, err := b.g.Delete(ctx, &pb.DeleteParams{ 821 | Uuid: uu, 822 | Start: start, 823 | End: end, 824 | }) 825 | if err != nil { 826 | return 0, err 827 | } 828 | if rv.Stat != nil { 829 | return 0, &CodedError{rv.Stat} 830 | } 831 | return rv.VersionMajor, nil 832 | } 833 | 834 | //Flush is a low level function, rather use Stream.Flush() 835 | func (b *Endpoint) Flush(ctx context.Context, uu uuid.UUID) error { 836 | rv, err := b.g.Flush(ctx, &pb.FlushParams{ 837 | Uuid: uu, 838 | }) 839 | if err != nil { 840 | return err 841 | } 842 | if rv.Stat != nil { 843 | return &CodedError{rv.Stat} 844 | } 845 | return nil 846 | } 847 | 848 | //Obliterate is a low level function, rather use Stream.Obliterate() 849 | func (b *Endpoint) Obliterate(ctx context.Context, uu uuid.UUID) error { 850 | rv, err := b.g.Obliterate(ctx, &pb.ObliterateParams{ 851 | Uuid: uu, 852 | }) 853 | if err != nil { 854 | return err 855 | } 856 | if rv.Stat != nil { 857 | return &CodedError{rv.Stat} 858 | } 859 | return nil 860 | } 861 | 862 | //Info is a low level function, rather use BTrDB.Info() 863 | func (b *Endpoint) Info(ctx context.Context) (*MASH, *pb.InfoResponse, error) { 864 | rv, err := b.g.Info(ctx, &pb.InfoParams{}) 865 | if err != nil { 866 | return nil, nil, err 867 | } 868 | if rv.Stat != nil { 869 | return nil, nil, &CodedError{rv.Stat} 870 | } 871 | mrv := &MASH{rv.Mash, nil} 872 | if rv.Mash != nil { 873 | mrv.precalculate() 874 | } 875 | return mrv, rv, nil 876 | } 877 | 878 | //Nearest is a low level function, rather use Stream.Nearest() 879 | func (b *Endpoint) Nearest(ctx context.Context, uu uuid.UUID, time int64, version uint64, backward bool) (RawPoint, uint64, error) { 880 | rv, err := b.g.Nearest(ctx, &pb.NearestParams{ 881 | Uuid: uu, 882 | Time: time, 883 | VersionMajor: version, 884 | Backward: backward, 885 | }) 886 | if err != nil { 887 | return RawPoint{}, 0, err 888 | } 889 | if rv.Stat != nil { 890 | return RawPoint{}, 0, &CodedError{rv.Stat} 891 | } 892 | return RawPoint{Time: rv.Value.Time, Value: rv.Value.Value}, rv.VersionMajor, nil 893 | } 894 | 895 | type ReducedResolutionRange struct { 896 | Start int64 897 | End int64 898 | Resolution uint32 899 | } 900 | 901 | type CompactionConfig struct { 902 | // Accessing versions LESS than this is not allowed 903 | CompactedVersion uint64 904 | // For every timestamp >= Start and < End in this list, 905 | // we cannot traverse the tree < Resolution. 906 | // These ranges are the new ones you want to add, not the full list 907 | ReducedResolutionRanges []*ReducedResolutionRange 908 | // Addresses less than this will be moved to the archive storage soon 909 | // You can't set this to less than it is, so zero means leave as is 910 | TargetArchiveHorizon uint64 911 | } 912 | 913 | //SetCompactionConfig is a low level function, use Stream.SetCompactionConfig instead 914 | func (b *Endpoint) SetCompactionConfig(ctx context.Context, uu uuid.UUID, cfg *CompactionConfig) error { 915 | rrz := make([]*pb.ReducedResolutionRange, len(cfg.ReducedResolutionRanges)) 916 | for i, r := range cfg.ReducedResolutionRanges { 917 | rrz[i] = &pb.ReducedResolutionRange{ 918 | Start: r.Start, 919 | End: r.End, 920 | Resolution: r.Resolution, 921 | } 922 | } 923 | rv, err := b.g.SetCompactionConfig(ctx, &pb.SetCompactionConfigParams{ 924 | Uuid: uu, 925 | CompactedVersion: cfg.CompactedVersion, 926 | ReducedResolutionRanges: rrz, 927 | TargetArchiveHorizon: cfg.TargetArchiveHorizon, 928 | }) 929 | if err != nil { 930 | return err 931 | } 932 | if rv.Stat != nil { 933 | return &CodedError{rv.Stat} 934 | } 935 | return nil 936 | } 937 | 938 | //GetCompactionConfig is a low level function, use Stream.GetCompactionConfig instead 939 | func (b *Endpoint) GetCompactionConfig(ctx context.Context, uu uuid.UUID) (cfg *CompactionConfig, majVersion uint64, err error) { 940 | rv, err := b.g.GetCompactionConfig(ctx, &pb.GetCompactionConfigParams{ 941 | Uuid: uu, 942 | }) 943 | if err != nil { 944 | return nil, 0, err 945 | } 946 | if rv.Stat != nil { 947 | return nil, 0, &CodedError{rv.Stat} 948 | } 949 | 950 | rrz := make([]*ReducedResolutionRange, len(rv.ReducedResolutionRanges)) 951 | for i, r := range rv.ReducedResolutionRanges { 952 | rrz[i] = &ReducedResolutionRange{ 953 | Start: r.Start, 954 | End: r.End, 955 | Resolution: r.Resolution, 956 | } 957 | } 958 | cfg = &CompactionConfig{ 959 | CompactedVersion: rv.CompactedVersion, 960 | ReducedResolutionRanges: rrz, 961 | TargetArchiveHorizon: rv.TargetArchiveHorizon, 962 | } 963 | return cfg, rv.LatestMajorVersion, nil 964 | } 965 | 966 | type ChangedRange struct { 967 | Version uint64 968 | Start int64 969 | End int64 970 | } 971 | 972 | //Changes is a low level function, rather use BTrDB.Changes() 973 | func (b *Endpoint) Changes(ctx context.Context, uu uuid.UUID, fromVersion uint64, toVersion uint64, resolution uint8) (chan ChangedRange, chan uint64, chan error) { 974 | rv, err := b.g.Changes(ctx, &pb.ChangesParams{ 975 | Uuid: uu, 976 | FromMajor: fromVersion, 977 | ToMajor: toVersion, 978 | Resolution: uint32(resolution), 979 | }) 980 | rvc := make(chan ChangedRange, 100) 981 | rvv := make(chan uint64, 1) 982 | rve := make(chan error, 1) 983 | wroteVer := false 984 | if err != nil { 985 | close(rvc) 986 | close(rvv) 987 | rve <- err 988 | close(rve) 989 | return rvc, rvv, rve 990 | } 991 | go func() { 992 | for { 993 | cr, err := rv.Recv() 994 | if err == io.EOF { 995 | close(rvc) 996 | close(rvv) 997 | close(rve) 998 | return 999 | } 1000 | if err != nil { 1001 | close(rvc) 1002 | close(rvv) 1003 | rve <- err 1004 | close(rve) 1005 | return 1006 | } 1007 | if cr.Stat != nil { 1008 | close(rvc) 1009 | close(rvv) 1010 | rve <- &CodedError{cr.Stat} 1011 | close(rve) 1012 | return 1013 | } 1014 | if !wroteVer { 1015 | rvv <- cr.VersionMajor 1016 | wroteVer = true 1017 | } 1018 | for _, x := range cr.Ranges { 1019 | rvc <- ChangedRange{Version: cr.VersionMajor, Start: x.Start, End: x.End} 1020 | } 1021 | } 1022 | }() 1023 | return rvc, rvv, rve 1024 | } 1025 | 1026 | //SubscribeTo is a low level function that forks a goroutine in the background and fills the provided channls. 1027 | //It is assumed the caller has already ensured that this endpoint is responsible for the provided uuids. 1028 | func (b *Endpoint) SubscribeTo(ctx context.Context, uuid []uuid.UUID, c chan SubRecord, errc chan error) { 1029 | by := make([][]byte, len(uuid)) 1030 | for i := range uuid { 1031 | by[i] = []byte(uuid[i]) 1032 | } 1033 | stream, err := b.g.Subscribe(ctx, &pb.SubscriptionParams{ 1034 | Uuid: by, 1035 | }) 1036 | if err != nil { 1037 | errc <- err 1038 | close(c) 1039 | return 1040 | } 1041 | 1042 | go func() { 1043 | for { 1044 | rp, err := stream.Recv() 1045 | if err != nil { 1046 | errc <- err 1047 | close(c) 1048 | return 1049 | } 1050 | if rp.Stat != nil { 1051 | errc <- errors.New(rp.Stat.Msg) 1052 | close(c) 1053 | return 1054 | } 1055 | sr := SubRecord{ 1056 | ID: rp.Uuid, 1057 | Val: make([]RawPoint, len(rp.Values)), 1058 | } 1059 | for i := range rp.Values { 1060 | sr.Val[i] = RawPoint{rp.Values[i].Time, rp.Values[i].Value} 1061 | } 1062 | c <- sr 1063 | } 1064 | }() 1065 | } 1066 | -------------------------------------------------------------------------------- /examples/insert_test.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "testing" 8 | "time" 9 | 10 | "github.com/pborman/uuid" 11 | 12 | btrdb "github.com/BTrDB/btrdb/v5" 13 | ) 14 | 15 | func TestInsertingProceduralData(t *testing.T) { 16 | //First connect to the cluster. In BTrDB v4 we are advocating that all 17 | //programs use environment variables to specify the endpoint rather 18 | //than assuming specific addresses: 19 | //Set $BTRDB_ENDPOINTS to 20 | //"server1:4410;server2:4410..." 21 | //Note that not all endpoints need be listed, but it will make this 22 | //program more resilient if you specify more or all of the endpoints 23 | db, err := btrdb.ConnectAuth(context.TODO(), os.Getenv("BTRDB_APIKEY"), btrdb.EndpointsFromEnv()...) 24 | if err != nil { 25 | t.Fatalf("Unexpected connection error: %v", err) 26 | } 27 | 28 | //Streams must be created before use 29 | uu := uuid.NewRandom() 30 | //A collection is a small group of streams (<100 is best) generally associated 31 | //with a single device or service. BTrDB is designed for lots of small collections 32 | //not small numbers of big collections 33 | collection := fmt.Sprintf("test/inserting_procedural_data.%d", time.Now().UnixNano()) 34 | //The annotation is used to store (mutable) extra data with the stream. It 35 | //is technically just a byte array, but we prefer people use msgpacked objects. 36 | //the tooling is not quite there to make this easy, so its ok to make this nil 37 | //for now 38 | var annotation map[string]*string = nil 39 | 40 | stream, err := db.Create(context.TODO(), uu, collection, btrdb.OptKV("name", "test"), annotation) 41 | if err != nil { 42 | t.Fatalf("Unexpected creation error: %v", err) 43 | } 44 | 45 | //Now you manipulate the stream: 46 | err = stream.InsertTV(context.TODO(), 47 | []int64{100e6, 200e6, 300e6, 400e6}, 48 | []float64{1.1, 2.2, 3.3, 4.4}) 49 | if err != nil { 50 | t.Fatalf("Unexpected insert error: %v", err) 51 | } 52 | 53 | //Start = -1000ns, End = 1000ns, Width = 150ns, Depth = 2^0 (all the way), Version = latest 54 | rvchan, ver, errc := stream.Windows(context.TODO(), -1000e6, 1000e6, 150e6, 0, btrdb.LatestVersion) 55 | _ = ver //don't use this, that's ok 56 | for result := range rvchan { 57 | fmt.Printf("Window @%d min=%.2f mean=%.2f max=%.2f count=%d\n", 58 | result.Time, result.Min, result.Mean, result.Max, result.Count) 59 | } 60 | if e := <-errc; e != nil { 61 | t.Fatalf("Got an error: %v", e) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/BTrDB/btrdb/v5 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/golang/protobuf v1.5.2 7 | github.com/google/uuid v1.3.0 // indirect 8 | github.com/grpc-ecosystem/grpc-gateway v1.16.0 9 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.0 10 | github.com/huichen/murmur v0.0.0-20130808212358-e0489551cf51 11 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 12 | github.com/pborman/uuid v1.2.1 13 | google.golang.org/api v0.84.0 14 | google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f 15 | google.golang.org/grpc v1.48.0 16 | google.golang.org/protobuf v1.28.0 17 | ) 18 | -------------------------------------------------------------------------------- /mash.go: -------------------------------------------------------------------------------- 1 | package btrdb 2 | 3 | import ( 4 | "strings" 5 | 6 | pb "github.com/BTrDB/btrdb/v5/v5api" 7 | "github.com/huichen/murmur" 8 | "github.com/pborman/uuid" 9 | ) 10 | 11 | //The MASH struct (Master Allocation by Stable Hashing) contains information 12 | //about the cluster and which fraction of the uuid space is being served by 13 | //which endpoints. Generally you will not need to use this, but it is handy 14 | //for checking the cluster is healthy. 15 | type MASH struct { 16 | *pb.Mash 17 | eps []mashEndpoint 18 | } 19 | 20 | type mashEndpoint struct { 21 | start int64 22 | end int64 23 | hash uint32 24 | grpc []string 25 | } 26 | 27 | func (m *MASH) pbEndpointFor(uuid uuid.UUID) *pb.Member { 28 | hsh := int64(murmur.Murmur3(uuid[:])) 29 | for _, mbr := range m.GetMembers() { 30 | s := mbr.GetStart() 31 | e := mbr.GetEnd() 32 | if hsh >= s && hsh < e { 33 | return mbr 34 | } 35 | } 36 | return nil 37 | } 38 | 39 | //EndpointFor will take a uuid and return the connection details for the 40 | //endpoint that can service a write to that uuid. This is a low level function. 41 | func (m *MASH) EndpointFor(uuid uuid.UUID) (found bool, hash uint32, addrs []string) { 42 | hsh := int64(murmur.Murmur3(uuid[:])) 43 | for _, e := range m.eps { 44 | if e.start <= hsh && e.end > hsh { 45 | return true, e.hash, e.grpc 46 | } 47 | } 48 | return false, 0, nil 49 | } 50 | 51 | //Called after mash pb obj is populated. Can be used to fill in 52 | //read optimized data structures in the MASH object 53 | func (m *MASH) precalculate() { 54 | m.eps = []mashEndpoint{} 55 | for _, mbr := range m.Members { 56 | if mbr.In && mbr.Up && mbr.Start != mbr.End { 57 | seps := strings.Split(mbr.GrpcEndpoints, ";") 58 | m.eps = append(m.eps, mashEndpoint{ 59 | start: mbr.Start, 60 | end: mbr.End, 61 | hash: mbr.Hash, 62 | grpc: seps, 63 | }) 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /utils.go: -------------------------------------------------------------------------------- 1 | package btrdb 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strings" 7 | 8 | pb "github.com/BTrDB/btrdb/v5/v5api" 9 | ) 10 | 11 | //M is an alias to neaten code specifying tags: 12 | // btrdb.LookupStream(ctx, "mycollection", btrdb.M{"tagkey":"tagval"}) 13 | type M map[string]string 14 | 15 | //CodedError is an error that contains a numeric code. Most errors returned by 16 | //this package are actually *CodedError objects. Use ToCodedError() 17 | type CodedError struct { 18 | *pb.Status 19 | } 20 | 21 | //Error() implements the error interface 22 | func (ce *CodedError) Error() string { 23 | return fmt.Sprintf("[%d] %s", ce.Code, ce.Msg) 24 | } 25 | 26 | //ToCodedError can be used to convert any error into a CodedError. If the 27 | //error object is actually not coded, it will receive code 501. 28 | func ToCodedError(e error) *CodedError { 29 | if e == nil { 30 | return nil 31 | } else if ce, ok := e.(*CodedError); ok { 32 | return ce 33 | } else { 34 | s := pb.Status{Code: 501, Msg: e.Error()} 35 | return &CodedError{&s} 36 | } 37 | } 38 | 39 | //LatestVersion can be passed to any functions taking a version to use the 40 | //latest version of that stream 41 | const LatestVersion = 0 42 | 43 | //EndpointsFromEnv reads the environment variable BTRDB_ENDPOINTS of the format 44 | // server:port,server:port,server:port 45 | //and returns it as a string slice. This function is typically used as 46 | // btrdb.Connect(btrdb.EndpointsFromEnv()...) 47 | func EndpointsFromEnv() []string { 48 | endpoints := os.Getenv("BTRDB_ENDPOINTS") 49 | if endpoints == "" { 50 | return nil 51 | } 52 | spl := strings.Split(endpoints, ",") 53 | return spl 54 | } 55 | -------------------------------------------------------------------------------- /v5api/btrdb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | //BTrDB v5 API 3 | 4 | package v5api; 5 | option go_package = "./v5api"; 6 | import "google/api/annotations.proto"; 7 | 8 | service BTrDB { 9 | rpc RawValues(RawValuesParams) returns (stream RawValuesResponse) { 10 | option (google.api.http) = { 11 | post: "/v5/rawvalues" 12 | body: "*" 13 | }; 14 | } 15 | rpc MultiRawValues(MultiRawValuesParams) returns (stream MultiRawValuesResponse) { 16 | option (google.api.http) = { 17 | post: "/v5/multirawvalues" 18 | body: "*" 19 | }; 20 | } 21 | 22 | rpc AlignedWindows(AlignedWindowsParams) returns (stream AlignedWindowsResponse) { 23 | option (google.api.http) = { 24 | post: "/v5/alignedwindows" 25 | body: "*" 26 | }; 27 | } 28 | rpc Windows(WindowsParams) returns (stream WindowsResponse) { 29 | option (google.api.http) = { 30 | post: "/v5/windows" 31 | body: "*" 32 | }; 33 | } 34 | rpc StreamInfo(StreamInfoParams) returns (StreamInfoResponse) { 35 | option (google.api.http) = { 36 | post: "/v5/streaminfo" 37 | body: "*" 38 | }; 39 | } 40 | rpc SetStreamAnnotations(SetStreamAnnotationsParams) returns (SetStreamAnnotationsResponse) { 41 | option (google.api.http) = { 42 | post: "/v5/setstreamannotations" 43 | body: "*" 44 | }; 45 | } 46 | rpc SetStreamTags(SetStreamTagsParams) returns (SetStreamTagsResponse) { 47 | option (google.api.http) = { 48 | post: "/v5/setstreamtags" 49 | body: "*" 50 | }; 51 | } 52 | rpc Create(CreateParams) returns (CreateResponse) { 53 | option (google.api.http) = { 54 | post: "/v5/create" 55 | body: "*" 56 | }; 57 | } 58 | rpc ListCollections(ListCollectionsParams) returns (stream ListCollectionsResponse) { 59 | option (google.api.http) = { 60 | post: "/v5/listcollections" 61 | body: "*" 62 | }; 63 | } 64 | rpc LookupStreams(LookupStreamsParams) returns (stream LookupStreamsResponse) { 65 | option (google.api.http) = { 66 | post: "/v5/lookupstreams" 67 | body: "*" 68 | }; 69 | } 70 | rpc Nearest(NearestParams) returns (NearestResponse) { 71 | option (google.api.http) = { 72 | post: "/v5/nearest" 73 | body: "*" 74 | }; 75 | } 76 | rpc Changes(ChangesParams) returns (stream ChangesResponse) { 77 | option (google.api.http) = { 78 | post: "/v5/changes" 79 | body: "*" 80 | }; 81 | } 82 | rpc Insert(InsertParams) returns (InsertResponse) { 83 | option (google.api.http) = { 84 | post: "/v5/insert" 85 | body: "*" 86 | }; 87 | } 88 | rpc Delete(DeleteParams) returns (DeleteResponse) { 89 | option (google.api.http) = { 90 | post: "/v5/delete" 91 | body: "*" 92 | }; 93 | } 94 | rpc Info(InfoParams) returns (InfoResponse) { 95 | option (google.api.http) = { 96 | post: "/v5/info" 97 | body: "*" 98 | }; 99 | } 100 | rpc FaultInject(FaultInjectParams) returns (FaultInjectResponse) { 101 | option (google.api.http) = { 102 | post: "/v5/faultinject" 103 | body: "*" 104 | }; 105 | } 106 | rpc Flush(FlushParams) returns (FlushResponse) { 107 | option (google.api.http) = { 108 | post: "/v5/flush" 109 | body: "*" 110 | }; 111 | } 112 | rpc Obliterate(ObliterateParams) returns (ObliterateResponse) { 113 | option (google.api.http) = { 114 | post: "/v5/obliterate" 115 | body: "*" 116 | }; 117 | } 118 | 119 | rpc GetMetadataUsage(MetadataUsageParams) returns (MetadataUsageResponse) { 120 | option (google.api.http) = { 121 | post: "/v5/getmetadatausage" 122 | body: "*" 123 | }; 124 | } 125 | 126 | rpc GenerateCSV(GenerateCSVParams) returns (stream GenerateCSVResponse) { 127 | option (google.api.http) = { 128 | post: "/v5/generatecsv" 129 | body: "*" 130 | }; 131 | } 132 | 133 | rpc SQLQuery(SQLQueryParams) returns (stream SQLQueryResponse) { 134 | option (google.api.http) = { 135 | post: "/v5/sqlquery" 136 | body: "*" 137 | }; 138 | } 139 | 140 | rpc Subscribe(SubscriptionParams) returns (stream SubscriptionResp) { 141 | option (google.api.http) = { 142 | post: "/v5/subscribe" 143 | body: "*" 144 | }; 145 | } 146 | 147 | rpc SetCompactionConfig(SetCompactionConfigParams) returns (SetCompactionConfigResponse) { 148 | option (google.api.http) = { 149 | post: "/v5/setcompactionconfig" 150 | body: "*" 151 | }; 152 | } 153 | rpc GetCompactionConfig(GetCompactionConfigParams) returns (GetCompactionConfigResponse) { 154 | option (google.api.http) = { 155 | post: "/v5/getcompactionconfig" 156 | body: "*" 157 | }; 158 | } 159 | 160 | } 161 | 162 | message RawValuesParams { 163 | bytes uuid = 1; 164 | sfixed64 start = 2; 165 | sfixed64 end = 3; 166 | uint64 versionMajor = 4; 167 | } 168 | message RawValuesResponse { 169 | Status stat = 1; 170 | uint64 versionMajor = 2; 171 | uint64 versionMinor = 3; 172 | repeated RawPoint values = 4; 173 | } 174 | message MultiRawValuesParams { 175 | repeated bytes uuid = 1; 176 | sfixed64 start = 2; 177 | sfixed64 end = 3; 178 | uint64 versionMajor = 4; 179 | int64 periodNs = 5; 180 | } 181 | message MultiRawValuesResponse { 182 | Status stat = 1; 183 | repeated uint64 versionMajor = 2; 184 | repeated uint64 versionMinor = 3; 185 | repeated RawPointVec values = 4; 186 | } 187 | message RawPointVec { 188 | sfixed64 time = 1; 189 | repeated double value = 2; 190 | }; 191 | message AlignedWindowsParams { 192 | bytes uuid = 1; 193 | sfixed64 start = 2; 194 | sfixed64 end = 3; 195 | uint64 versionMajor = 4; 196 | uint32 pointWidth = 5; 197 | } 198 | message AlignedWindowsResponse { 199 | Status stat = 1; 200 | uint64 versionMajor = 2; 201 | uint64 versionMinor = 3; 202 | repeated StatPoint values = 4; 203 | } 204 | message WindowsParams { 205 | bytes uuid = 1; 206 | sfixed64 start = 2; 207 | sfixed64 end = 3; 208 | uint64 versionMajor = 4; 209 | uint64 width = 5; 210 | uint32 depth = 6; 211 | } 212 | message WindowsResponse { 213 | Status stat = 1; 214 | uint64 versionMajor = 2; 215 | uint64 versionMinor = 3; 216 | repeated StatPoint values = 4; 217 | } 218 | message StreamInfoParams { 219 | bytes uuid = 1; 220 | bool omitVersion = 2; 221 | bool omitDescriptor = 3; 222 | Role role = 100; 223 | } 224 | message StreamInfoResponse { 225 | Status stat = 1; 226 | uint64 versionMajor = 2; 227 | uint64 versionMinor = 3; 228 | StreamDescriptor descriptor = 4; 229 | } 230 | message StreamDescriptor { 231 | bytes uuid = 1; 232 | string collection = 2; 233 | repeated KeyOptValue tags = 3; 234 | repeated KeyOptValue annotations = 4; 235 | uint64 propertyVersion = 5; 236 | } 237 | message SetStreamAnnotationsParams { 238 | bytes uuid = 1; 239 | uint64 expectedPropertyVersion = 2; 240 | repeated KeyOptValue changes = 3; 241 | repeated string removals = 4; 242 | } 243 | message SetStreamAnnotationsResponse { 244 | Status stat = 1; 245 | } 246 | message SetStreamTagsParams { 247 | bytes uuid = 1; 248 | uint64 expectedPropertyVersion = 2; 249 | repeated KeyOptValue tags = 3; 250 | string collection = 4; 251 | repeated string remove = 5; 252 | } 253 | message SetStreamTagsResponse { 254 | Status stat = 1; 255 | } 256 | message CreateParams { 257 | bytes uuid = 1; 258 | string collection = 2; 259 | repeated KeyOptValue tags = 3; 260 | repeated KeyOptValue annotations = 4; 261 | } 262 | message CreateResponse { 263 | Status stat = 1; 264 | } 265 | message MetadataUsageParams { 266 | string prefix = 1; 267 | Role role = 100; 268 | } 269 | message MetadataUsageResponse { 270 | Status stat = 1; 271 | repeated KeyCount tags = 2; 272 | repeated KeyCount annotations = 3; 273 | } 274 | message KeyCount { 275 | string key = 1; 276 | uint64 count = 2; 277 | } 278 | message ListCollectionsParams { 279 | string prefix = 1; 280 | Role role = 100; 281 | } 282 | message ListCollectionsResponse { 283 | Status stat = 1; 284 | repeated string collections = 2; 285 | } 286 | message LookupStreamsParams { 287 | string collection = 1; 288 | bool isCollectionPrefix = 2; 289 | repeated KeyOptValue tags = 3; 290 | repeated KeyOptValue annotations = 4; 291 | Role role = 100; 292 | } 293 | message LookupStreamsResponse { 294 | Status stat = 1; 295 | repeated StreamDescriptor results = 2; 296 | } 297 | message NearestParams { 298 | bytes uuid = 1; 299 | sfixed64 time = 2; 300 | uint64 versionMajor = 3; 301 | bool backward = 4; 302 | } 303 | message NearestResponse { 304 | Status stat = 1; 305 | uint64 versionMajor = 2; 306 | uint64 versionMinor = 3; 307 | RawPoint value = 4; 308 | } 309 | message ChangesParams { 310 | bytes uuid = 1; 311 | uint64 fromMajor = 2; 312 | uint64 toMajor = 3; 313 | uint32 resolution = 4; 314 | } 315 | message ChangesResponse { 316 | Status stat = 1; 317 | uint64 versionMajor = 2; 318 | uint64 versionMinor = 3; 319 | repeated ChangedRange ranges = 4; 320 | } 321 | enum MergePolicy { 322 | NEVER = 0; // Never merge 323 | EQUAL = 1; // Merge identical (key, value) pairs 324 | RETAIN = 2; // When timestamps are equal, keep old value 325 | REPLACE = 3; // When timestamps are equal, keep new value 326 | } 327 | message RoundSpec { 328 | oneof spec { 329 | int32 bits = 2; // Round to a bit boundary 330 | } 331 | } 332 | message InsertParams { 333 | bytes uuid = 1; 334 | bool sync = 2; 335 | MergePolicy merge_policy = 4; 336 | RoundSpec rounding = 5; 337 | repeated RawPoint values = 3; 338 | } 339 | message InsertResponse { 340 | Status stat = 1; 341 | uint64 versionMajor = 2; 342 | uint64 versionMinor = 3; 343 | } 344 | message DeleteParams { 345 | bytes uuid = 1; 346 | sfixed64 start = 2; 347 | sfixed64 end = 3; 348 | } 349 | message DeleteResponse { 350 | Status stat = 1; 351 | uint64 versionMajor = 2; 352 | uint64 versionMinor = 3; 353 | } 354 | message InfoParams { 355 | 356 | } 357 | message InfoResponse { 358 | Status stat = 1; 359 | Mash mash = 2; 360 | uint32 majorVersion = 3; 361 | uint32 minorVersion = 4; 362 | string build = 5; 363 | ProxyInfo proxy = 6; 364 | } 365 | message ProxyInfo { 366 | repeated string proxyEndpoints = 1; 367 | } 368 | message FaultInjectParams { 369 | uint64 type = 1; 370 | bytes params = 2; 371 | } 372 | message FaultInjectResponse { 373 | Status stat = 1; 374 | bytes rv = 2; 375 | } 376 | message FlushParams { 377 | bytes uuid = 1; 378 | } 379 | message FlushResponse { 380 | Status stat = 1; 381 | uint64 versionMajor = 2; 382 | uint64 versionMinor = 3; 383 | } 384 | message ObliterateParams { 385 | bytes uuid = 1; 386 | } 387 | message ObliterateResponse { 388 | Status stat = 1; 389 | } 390 | message RawPoint { 391 | sfixed64 time = 1; 392 | double value = 2; 393 | } 394 | message StatPoint { 395 | sfixed64 time = 1; 396 | double min = 2; 397 | double mean = 3; 398 | double max = 4; 399 | fixed64 count = 5; 400 | double stddev = 6; 401 | } 402 | message ChangedRange { 403 | sfixed64 start = 1; 404 | sfixed64 end = 2; 405 | } 406 | message Status { 407 | uint32 code = 1; 408 | string msg = 2; 409 | Mash mash = 3; 410 | } 411 | message Mash { 412 | int64 revision = 1; 413 | string leader = 2; 414 | int64 leaderRevision = 3; 415 | int64 totalWeight = 4; 416 | bool healthy = 5; 417 | double unmapped = 6; 418 | repeated Member members = 7; 419 | } 420 | message Member { 421 | uint32 hash = 1; 422 | string nodename = 2; 423 | bool up = 3; 424 | bool in = 4; 425 | bool enabled = 5; 426 | int64 start = 6; 427 | int64 end = 7; 428 | int64 weight = 8; 429 | double readPreference = 9; 430 | string httpEndpoints = 10; 431 | string grpcEndpoints = 11; 432 | } 433 | message KeyOptValue { 434 | string key = 1; 435 | OptValue val = 2; 436 | } 437 | message OptValue { 438 | string value = 1; 439 | } 440 | message KeyValue { 441 | string key = 1; 442 | string value = 2; 443 | } 444 | 445 | message StreamCSVConfig { 446 | uint64 version = 1; 447 | string label = 2; 448 | bytes uuid = 3; 449 | } 450 | message GenerateCSVParams { 451 | enum QueryType { 452 | ALIGNED_WINDOWS_QUERY = 0; 453 | WINDOWS_QUERY = 1; 454 | RAW_QUERY = 2; 455 | } 456 | QueryType queryType = 1; 457 | int64 startTime = 2; 458 | int64 endTime = 3; 459 | uint64 windowSize = 4; 460 | uint32 depth = 5; 461 | bool includeVersions = 6; 462 | repeated StreamCSVConfig streams = 7; 463 | } 464 | message GenerateCSVResponse { 465 | Status stat = 1; 466 | bool isHeader = 2; 467 | repeated string row = 3; 468 | } 469 | message SQLQueryParams { 470 | string query = 1; 471 | repeated string params = 2; 472 | Role role = 100; 473 | } 474 | message SQLQueryResponse { 475 | Status stat = 1; 476 | repeated bytes SQLQueryRow = 2; 477 | } 478 | 479 | message Role { 480 | string name = 1; 481 | } 482 | 483 | message SetCompactionConfigParams { 484 | //Which stream to configure 485 | bytes uuid = 1; 486 | 487 | //Accessing versions LESS than this is not allowed 488 | uint64 CompactedVersion = 2; 489 | 490 | //For every timestamp >= Start and < End in this list, 491 | //we cannot traverse the tree < Resolution. 492 | //These ranges are the new ones you want to add, not the full list 493 | repeated ReducedResolutionRange reducedResolutionRanges = 3; 494 | 495 | // Addresses less than this will be moved to the archive storage soon 496 | // You can't set this to less than it is, so zero means leave as is 497 | uint64 targetArchiveHorizon = 4; 498 | } 499 | 500 | message SetCompactionConfigResponse { 501 | Status stat = 1; 502 | } 503 | 504 | message GetCompactionConfigParams { 505 | //Which stream to query 506 | bytes uuid = 1; 507 | } 508 | 509 | message GetCompactionConfigResponse { 510 | Status stat = 1; 511 | 512 | //The latest version of the stream, as returned by StreamInfo 513 | uint64 LatestMajorVersion = 2; 514 | 515 | //Accessing versions LESS than this is not allowed 516 | uint64 CompactedVersion = 3; 517 | 518 | //For every timestamp >= Start and < End in this list, 519 | //we cannot traverse the tree < Resolution. 520 | repeated ReducedResolutionRange reducedResolutionRanges = 4; 521 | 522 | // Addresses less than this will be moved to the archive storage soon 523 | uint64 targetArchiveHorizon = 5; 524 | } 525 | 526 | message ReducedResolutionRange { 527 | int64 Start = 1; 528 | int64 End = 2; 529 | uint32 Resolution = 3; 530 | } 531 | message SubscriptionParams { 532 | repeated bytes uuid = 1; 533 | } 534 | 535 | message SubscriptionResp { 536 | Status stat = 1; 537 | bytes uuid = 3; 538 | repeated RawPoint values = 2; 539 | } 540 | -------------------------------------------------------------------------------- /v5api/btrdb.swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "title": "v5api/btrdb.proto", 5 | "version": "5.12.0" 6 | }, 7 | "schemes": [ 8 | "http", 9 | "https" 10 | ], 11 | "consumes": [ 12 | "application/json" 13 | ], 14 | "produces": [ 15 | "application/json" 16 | ], 17 | "paths": { 18 | "/v5/alignedwindows": { 19 | "post": { 20 | "operationId": "AlignedWindows", 21 | "responses": { 22 | "200": { 23 | "description": "A successful response.(streaming responses)", 24 | "schema": { 25 | "$ref": "#/x-stream-definitions/v5apiAlignedWindowsResponse" 26 | } 27 | } 28 | }, 29 | "parameters": [ 30 | { 31 | "name": "body", 32 | "in": "body", 33 | "required": true, 34 | "schema": { 35 | "$ref": "#/definitions/v5apiAlignedWindowsParams" 36 | } 37 | } 38 | ], 39 | "tags": [ 40 | "BTrDB" 41 | ] 42 | } 43 | }, 44 | "/v5/changes": { 45 | "post": { 46 | "operationId": "Changes", 47 | "responses": { 48 | "200": { 49 | "description": "A successful response.(streaming responses)", 50 | "schema": { 51 | "$ref": "#/x-stream-definitions/v5apiChangesResponse" 52 | } 53 | } 54 | }, 55 | "parameters": [ 56 | { 57 | "name": "body", 58 | "in": "body", 59 | "required": true, 60 | "schema": { 61 | "$ref": "#/definitions/v5apiChangesParams" 62 | } 63 | } 64 | ], 65 | "tags": [ 66 | "BTrDB" 67 | ] 68 | } 69 | }, 70 | "/v5/create": { 71 | "post": { 72 | "operationId": "Create", 73 | "responses": { 74 | "200": { 75 | "description": "A successful response.", 76 | "schema": { 77 | "$ref": "#/definitions/v5apiCreateResponse" 78 | } 79 | } 80 | }, 81 | "parameters": [ 82 | { 83 | "name": "body", 84 | "in": "body", 85 | "required": true, 86 | "schema": { 87 | "$ref": "#/definitions/v5apiCreateParams" 88 | } 89 | } 90 | ], 91 | "tags": [ 92 | "BTrDB" 93 | ] 94 | } 95 | }, 96 | "/v5/delete": { 97 | "post": { 98 | "operationId": "Delete", 99 | "responses": { 100 | "200": { 101 | "description": "A successful response.", 102 | "schema": { 103 | "$ref": "#/definitions/v5apiDeleteResponse" 104 | } 105 | } 106 | }, 107 | "parameters": [ 108 | { 109 | "name": "body", 110 | "in": "body", 111 | "required": true, 112 | "schema": { 113 | "$ref": "#/definitions/v5apiDeleteParams" 114 | } 115 | } 116 | ], 117 | "tags": [ 118 | "BTrDB" 119 | ] 120 | } 121 | }, 122 | "/v5/faultinject": { 123 | "post": { 124 | "operationId": "FaultInject", 125 | "responses": { 126 | "200": { 127 | "description": "A successful response.", 128 | "schema": { 129 | "$ref": "#/definitions/v5apiFaultInjectResponse" 130 | } 131 | } 132 | }, 133 | "parameters": [ 134 | { 135 | "name": "body", 136 | "in": "body", 137 | "required": true, 138 | "schema": { 139 | "$ref": "#/definitions/v5apiFaultInjectParams" 140 | } 141 | } 142 | ], 143 | "tags": [ 144 | "BTrDB" 145 | ] 146 | } 147 | }, 148 | "/v5/flush": { 149 | "post": { 150 | "operationId": "Flush", 151 | "responses": { 152 | "200": { 153 | "description": "A successful response.", 154 | "schema": { 155 | "$ref": "#/definitions/v5apiFlushResponse" 156 | } 157 | } 158 | }, 159 | "parameters": [ 160 | { 161 | "name": "body", 162 | "in": "body", 163 | "required": true, 164 | "schema": { 165 | "$ref": "#/definitions/v5apiFlushParams" 166 | } 167 | } 168 | ], 169 | "tags": [ 170 | "BTrDB" 171 | ] 172 | } 173 | }, 174 | "/v5/generatecsv": { 175 | "post": { 176 | "operationId": "GenerateCSV", 177 | "responses": { 178 | "200": { 179 | "description": "A successful response.(streaming responses)", 180 | "schema": { 181 | "$ref": "#/x-stream-definitions/v5apiGenerateCSVResponse" 182 | } 183 | } 184 | }, 185 | "parameters": [ 186 | { 187 | "name": "body", 188 | "in": "body", 189 | "required": true, 190 | "schema": { 191 | "$ref": "#/definitions/v5apiGenerateCSVParams" 192 | } 193 | } 194 | ], 195 | "tags": [ 196 | "BTrDB" 197 | ] 198 | } 199 | }, 200 | "/v5/getcompactionconfig": { 201 | "post": { 202 | "operationId": "GetCompactionConfig", 203 | "responses": { 204 | "200": { 205 | "description": "A successful response.", 206 | "schema": { 207 | "$ref": "#/definitions/v5apiGetCompactionConfigResponse" 208 | } 209 | } 210 | }, 211 | "parameters": [ 212 | { 213 | "name": "body", 214 | "in": "body", 215 | "required": true, 216 | "schema": { 217 | "$ref": "#/definitions/v5apiGetCompactionConfigParams" 218 | } 219 | } 220 | ], 221 | "tags": [ 222 | "BTrDB" 223 | ] 224 | } 225 | }, 226 | "/v5/getmetadatausage": { 227 | "post": { 228 | "operationId": "GetMetadataUsage", 229 | "responses": { 230 | "200": { 231 | "description": "A successful response.", 232 | "schema": { 233 | "$ref": "#/definitions/v5apiMetadataUsageResponse" 234 | } 235 | } 236 | }, 237 | "parameters": [ 238 | { 239 | "name": "body", 240 | "in": "body", 241 | "required": true, 242 | "schema": { 243 | "$ref": "#/definitions/v5apiMetadataUsageParams" 244 | } 245 | } 246 | ], 247 | "tags": [ 248 | "BTrDB" 249 | ] 250 | } 251 | }, 252 | "/v5/info": { 253 | "post": { 254 | "operationId": "Info", 255 | "responses": { 256 | "200": { 257 | "description": "A successful response.", 258 | "schema": { 259 | "$ref": "#/definitions/v5apiInfoResponse" 260 | } 261 | } 262 | }, 263 | "parameters": [ 264 | { 265 | "name": "body", 266 | "in": "body", 267 | "required": true, 268 | "schema": { 269 | "$ref": "#/definitions/v5apiInfoParams" 270 | } 271 | } 272 | ], 273 | "tags": [ 274 | "BTrDB" 275 | ] 276 | } 277 | }, 278 | "/v5/insert": { 279 | "post": { 280 | "operationId": "Insert", 281 | "responses": { 282 | "200": { 283 | "description": "A successful response.", 284 | "schema": { 285 | "$ref": "#/definitions/v5apiInsertResponse" 286 | } 287 | } 288 | }, 289 | "parameters": [ 290 | { 291 | "name": "body", 292 | "in": "body", 293 | "required": true, 294 | "schema": { 295 | "$ref": "#/definitions/v5apiInsertParams" 296 | } 297 | } 298 | ], 299 | "tags": [ 300 | "BTrDB" 301 | ] 302 | } 303 | }, 304 | "/v5/listcollections": { 305 | "post": { 306 | "operationId": "ListCollections", 307 | "responses": { 308 | "200": { 309 | "description": "A successful response.(streaming responses)", 310 | "schema": { 311 | "$ref": "#/x-stream-definitions/v5apiListCollectionsResponse" 312 | } 313 | } 314 | }, 315 | "parameters": [ 316 | { 317 | "name": "body", 318 | "in": "body", 319 | "required": true, 320 | "schema": { 321 | "$ref": "#/definitions/v5apiListCollectionsParams" 322 | } 323 | } 324 | ], 325 | "tags": [ 326 | "BTrDB" 327 | ] 328 | } 329 | }, 330 | "/v5/lookupstreams": { 331 | "post": { 332 | "operationId": "LookupStreams", 333 | "responses": { 334 | "200": { 335 | "description": "A successful response.(streaming responses)", 336 | "schema": { 337 | "$ref": "#/x-stream-definitions/v5apiLookupStreamsResponse" 338 | } 339 | } 340 | }, 341 | "parameters": [ 342 | { 343 | "name": "body", 344 | "in": "body", 345 | "required": true, 346 | "schema": { 347 | "$ref": "#/definitions/v5apiLookupStreamsParams" 348 | } 349 | } 350 | ], 351 | "tags": [ 352 | "BTrDB" 353 | ] 354 | } 355 | }, 356 | "/v5/nearest": { 357 | "post": { 358 | "operationId": "Nearest", 359 | "responses": { 360 | "200": { 361 | "description": "A successful response.", 362 | "schema": { 363 | "$ref": "#/definitions/v5apiNearestResponse" 364 | } 365 | } 366 | }, 367 | "parameters": [ 368 | { 369 | "name": "body", 370 | "in": "body", 371 | "required": true, 372 | "schema": { 373 | "$ref": "#/definitions/v5apiNearestParams" 374 | } 375 | } 376 | ], 377 | "tags": [ 378 | "BTrDB" 379 | ] 380 | } 381 | }, 382 | "/v5/obliterate": { 383 | "post": { 384 | "operationId": "Obliterate", 385 | "responses": { 386 | "200": { 387 | "description": "A successful response.", 388 | "schema": { 389 | "$ref": "#/definitions/v5apiObliterateResponse" 390 | } 391 | } 392 | }, 393 | "parameters": [ 394 | { 395 | "name": "body", 396 | "in": "body", 397 | "required": true, 398 | "schema": { 399 | "$ref": "#/definitions/v5apiObliterateParams" 400 | } 401 | } 402 | ], 403 | "tags": [ 404 | "BTrDB" 405 | ] 406 | } 407 | }, 408 | "/v5/rawvalues": { 409 | "post": { 410 | "operationId": "RawValues", 411 | "responses": { 412 | "200": { 413 | "description": "A successful response.(streaming responses)", 414 | "schema": { 415 | "$ref": "#/x-stream-definitions/v5apiRawValuesResponse" 416 | } 417 | } 418 | }, 419 | "parameters": [ 420 | { 421 | "name": "body", 422 | "in": "body", 423 | "required": true, 424 | "schema": { 425 | "$ref": "#/definitions/v5apiRawValuesParams" 426 | } 427 | } 428 | ], 429 | "tags": [ 430 | "BTrDB" 431 | ] 432 | } 433 | }, 434 | "/v5/setcompactionconfig": { 435 | "post": { 436 | "operationId": "SetCompactionConfig", 437 | "responses": { 438 | "200": { 439 | "description": "A successful response.", 440 | "schema": { 441 | "$ref": "#/definitions/v5apiSetCompactionConfigResponse" 442 | } 443 | } 444 | }, 445 | "parameters": [ 446 | { 447 | "name": "body", 448 | "in": "body", 449 | "required": true, 450 | "schema": { 451 | "$ref": "#/definitions/v5apiSetCompactionConfigParams" 452 | } 453 | } 454 | ], 455 | "tags": [ 456 | "BTrDB" 457 | ] 458 | } 459 | }, 460 | "/v5/setstreamannotations": { 461 | "post": { 462 | "operationId": "SetStreamAnnotations", 463 | "responses": { 464 | "200": { 465 | "description": "A successful response.", 466 | "schema": { 467 | "$ref": "#/definitions/v5apiSetStreamAnnotationsResponse" 468 | } 469 | } 470 | }, 471 | "parameters": [ 472 | { 473 | "name": "body", 474 | "in": "body", 475 | "required": true, 476 | "schema": { 477 | "$ref": "#/definitions/v5apiSetStreamAnnotationsParams" 478 | } 479 | } 480 | ], 481 | "tags": [ 482 | "BTrDB" 483 | ] 484 | } 485 | }, 486 | "/v5/setstreamtags": { 487 | "post": { 488 | "operationId": "SetStreamTags", 489 | "responses": { 490 | "200": { 491 | "description": "A successful response.", 492 | "schema": { 493 | "$ref": "#/definitions/v5apiSetStreamTagsResponse" 494 | } 495 | } 496 | }, 497 | "parameters": [ 498 | { 499 | "name": "body", 500 | "in": "body", 501 | "required": true, 502 | "schema": { 503 | "$ref": "#/definitions/v5apiSetStreamTagsParams" 504 | } 505 | } 506 | ], 507 | "tags": [ 508 | "BTrDB" 509 | ] 510 | } 511 | }, 512 | "/v5/sqlquery": { 513 | "post": { 514 | "operationId": "SQLQuery", 515 | "responses": { 516 | "200": { 517 | "description": "A successful response.(streaming responses)", 518 | "schema": { 519 | "$ref": "#/x-stream-definitions/v5apiSQLQueryResponse" 520 | } 521 | } 522 | }, 523 | "parameters": [ 524 | { 525 | "name": "body", 526 | "in": "body", 527 | "required": true, 528 | "schema": { 529 | "$ref": "#/definitions/v5apiSQLQueryParams" 530 | } 531 | } 532 | ], 533 | "tags": [ 534 | "BTrDB" 535 | ] 536 | } 537 | }, 538 | "/v5/streaminfo": { 539 | "post": { 540 | "operationId": "StreamInfo", 541 | "responses": { 542 | "200": { 543 | "description": "A successful response.", 544 | "schema": { 545 | "$ref": "#/definitions/v5apiStreamInfoResponse" 546 | } 547 | } 548 | }, 549 | "parameters": [ 550 | { 551 | "name": "body", 552 | "in": "body", 553 | "required": true, 554 | "schema": { 555 | "$ref": "#/definitions/v5apiStreamInfoParams" 556 | } 557 | } 558 | ], 559 | "tags": [ 560 | "BTrDB" 561 | ] 562 | } 563 | }, 564 | "/v5/windows": { 565 | "post": { 566 | "operationId": "Windows", 567 | "responses": { 568 | "200": { 569 | "description": "A successful response.(streaming responses)", 570 | "schema": { 571 | "$ref": "#/x-stream-definitions/v5apiWindowsResponse" 572 | } 573 | } 574 | }, 575 | "parameters": [ 576 | { 577 | "name": "body", 578 | "in": "body", 579 | "required": true, 580 | "schema": { 581 | "$ref": "#/definitions/v5apiWindowsParams" 582 | } 583 | } 584 | ], 585 | "tags": [ 586 | "BTrDB" 587 | ] 588 | } 589 | } 590 | }, 591 | "definitions": { 592 | "GenerateCSVParamsQueryType": { 593 | "type": "string", 594 | "enum": [ 595 | "ALIGNED_WINDOWS_QUERY", 596 | "WINDOWS_QUERY", 597 | "RAW_QUERY" 598 | ], 599 | "default": "ALIGNED_WINDOWS_QUERY" 600 | }, 601 | "protobufAny": { 602 | "type": "object", 603 | "properties": { 604 | "type_url": { 605 | "type": "string" 606 | }, 607 | "value": { 608 | "type": "string", 609 | "format": "byte" 610 | } 611 | } 612 | }, 613 | "runtimeStreamError": { 614 | "type": "object", 615 | "properties": { 616 | "grpc_code": { 617 | "type": "integer", 618 | "format": "int32" 619 | }, 620 | "http_code": { 621 | "type": "integer", 622 | "format": "int32" 623 | }, 624 | "message": { 625 | "type": "string" 626 | }, 627 | "http_status": { 628 | "type": "string" 629 | }, 630 | "details": { 631 | "type": "array", 632 | "items": { 633 | "$ref": "#/definitions/protobufAny" 634 | } 635 | } 636 | } 637 | }, 638 | "v5apiAlignedWindowsParams": { 639 | "type": "object", 640 | "properties": { 641 | "uuid": { 642 | "type": "string", 643 | "format": "byte" 644 | }, 645 | "start": { 646 | "type": "string", 647 | "format": "int64" 648 | }, 649 | "end": { 650 | "type": "string", 651 | "format": "int64" 652 | }, 653 | "versionMajor": { 654 | "type": "string", 655 | "format": "uint64" 656 | }, 657 | "pointWidth": { 658 | "type": "integer", 659 | "format": "int64" 660 | } 661 | } 662 | }, 663 | "v5apiAlignedWindowsResponse": { 664 | "type": "object", 665 | "properties": { 666 | "stat": { 667 | "$ref": "#/definitions/v5apiStatus" 668 | }, 669 | "versionMajor": { 670 | "type": "string", 671 | "format": "uint64" 672 | }, 673 | "versionMinor": { 674 | "type": "string", 675 | "format": "uint64" 676 | }, 677 | "values": { 678 | "type": "array", 679 | "items": { 680 | "$ref": "#/definitions/v5apiStatPoint" 681 | } 682 | } 683 | } 684 | }, 685 | "v5apiChangedRange": { 686 | "type": "object", 687 | "properties": { 688 | "start": { 689 | "type": "string", 690 | "format": "int64" 691 | }, 692 | "end": { 693 | "type": "string", 694 | "format": "int64" 695 | } 696 | } 697 | }, 698 | "v5apiChangesParams": { 699 | "type": "object", 700 | "properties": { 701 | "uuid": { 702 | "type": "string", 703 | "format": "byte" 704 | }, 705 | "fromMajor": { 706 | "type": "string", 707 | "format": "uint64" 708 | }, 709 | "toMajor": { 710 | "type": "string", 711 | "format": "uint64" 712 | }, 713 | "resolution": { 714 | "type": "integer", 715 | "format": "int64" 716 | } 717 | } 718 | }, 719 | "v5apiChangesResponse": { 720 | "type": "object", 721 | "properties": { 722 | "stat": { 723 | "$ref": "#/definitions/v5apiStatus" 724 | }, 725 | "versionMajor": { 726 | "type": "string", 727 | "format": "uint64" 728 | }, 729 | "versionMinor": { 730 | "type": "string", 731 | "format": "uint64" 732 | }, 733 | "ranges": { 734 | "type": "array", 735 | "items": { 736 | "$ref": "#/definitions/v5apiChangedRange" 737 | } 738 | } 739 | } 740 | }, 741 | "v5apiCreateParams": { 742 | "type": "object", 743 | "properties": { 744 | "uuid": { 745 | "type": "string", 746 | "format": "byte" 747 | }, 748 | "collection": { 749 | "type": "string" 750 | }, 751 | "tags": { 752 | "type": "array", 753 | "items": { 754 | "$ref": "#/definitions/v5apiKeyOptValue" 755 | } 756 | }, 757 | "annotations": { 758 | "type": "array", 759 | "items": { 760 | "$ref": "#/definitions/v5apiKeyOptValue" 761 | } 762 | } 763 | } 764 | }, 765 | "v5apiCreateResponse": { 766 | "type": "object", 767 | "properties": { 768 | "stat": { 769 | "$ref": "#/definitions/v5apiStatus" 770 | } 771 | } 772 | }, 773 | "v5apiDeleteParams": { 774 | "type": "object", 775 | "properties": { 776 | "uuid": { 777 | "type": "string", 778 | "format": "byte" 779 | }, 780 | "start": { 781 | "type": "string", 782 | "format": "int64" 783 | }, 784 | "end": { 785 | "type": "string", 786 | "format": "int64" 787 | } 788 | } 789 | }, 790 | "v5apiDeleteResponse": { 791 | "type": "object", 792 | "properties": { 793 | "stat": { 794 | "$ref": "#/definitions/v5apiStatus" 795 | }, 796 | "versionMajor": { 797 | "type": "string", 798 | "format": "uint64" 799 | }, 800 | "versionMinor": { 801 | "type": "string", 802 | "format": "uint64" 803 | } 804 | } 805 | }, 806 | "v5apiFaultInjectParams": { 807 | "type": "object", 808 | "properties": { 809 | "type": { 810 | "type": "string", 811 | "format": "uint64" 812 | }, 813 | "params": { 814 | "type": "string", 815 | "format": "byte" 816 | } 817 | } 818 | }, 819 | "v5apiFaultInjectResponse": { 820 | "type": "object", 821 | "properties": { 822 | "stat": { 823 | "$ref": "#/definitions/v5apiStatus" 824 | }, 825 | "rv": { 826 | "type": "string", 827 | "format": "byte" 828 | } 829 | } 830 | }, 831 | "v5apiFlushParams": { 832 | "type": "object", 833 | "properties": { 834 | "uuid": { 835 | "type": "string", 836 | "format": "byte" 837 | } 838 | } 839 | }, 840 | "v5apiFlushResponse": { 841 | "type": "object", 842 | "properties": { 843 | "stat": { 844 | "$ref": "#/definitions/v5apiStatus" 845 | }, 846 | "versionMajor": { 847 | "type": "string", 848 | "format": "uint64" 849 | }, 850 | "versionMinor": { 851 | "type": "string", 852 | "format": "uint64" 853 | } 854 | } 855 | }, 856 | "v5apiGenerateCSVParams": { 857 | "type": "object", 858 | "properties": { 859 | "queryType": { 860 | "$ref": "#/definitions/GenerateCSVParamsQueryType" 861 | }, 862 | "startTime": { 863 | "type": "string", 864 | "format": "int64" 865 | }, 866 | "endTime": { 867 | "type": "string", 868 | "format": "int64" 869 | }, 870 | "windowSize": { 871 | "type": "string", 872 | "format": "uint64" 873 | }, 874 | "depth": { 875 | "type": "integer", 876 | "format": "int64" 877 | }, 878 | "includeVersions": { 879 | "type": "boolean", 880 | "format": "boolean" 881 | }, 882 | "streams": { 883 | "type": "array", 884 | "items": { 885 | "$ref": "#/definitions/v5apiStreamCSVConfig" 886 | } 887 | } 888 | } 889 | }, 890 | "v5apiGenerateCSVResponse": { 891 | "type": "object", 892 | "properties": { 893 | "stat": { 894 | "$ref": "#/definitions/v5apiStatus" 895 | }, 896 | "isHeader": { 897 | "type": "boolean", 898 | "format": "boolean" 899 | }, 900 | "row": { 901 | "type": "array", 902 | "items": { 903 | "type": "string" 904 | } 905 | } 906 | } 907 | }, 908 | "v5apiGetCompactionConfigParams": { 909 | "type": "object", 910 | "properties": { 911 | "uuid": { 912 | "type": "string", 913 | "format": "byte", 914 | "title": "Which stream to query" 915 | } 916 | } 917 | }, 918 | "v5apiGetCompactionConfigResponse": { 919 | "type": "object", 920 | "properties": { 921 | "stat": { 922 | "$ref": "#/definitions/v5apiStatus" 923 | }, 924 | "LatestMajorVersion": { 925 | "type": "string", 926 | "format": "uint64", 927 | "title": "The latest version of the stream, as returned by StreamInfo" 928 | }, 929 | "CompactedVersion": { 930 | "type": "string", 931 | "format": "uint64", 932 | "title": "Accessing versions LESS than this is not allowed" 933 | }, 934 | "reducedResolutionRanges": { 935 | "type": "array", 936 | "items": { 937 | "$ref": "#/definitions/v5apiReducedResolutionRange" 938 | }, 939 | "description": "For every timestamp \u003e= Start and \u003c End in this list,\nwe cannot traverse the tree \u003c Resolution." 940 | }, 941 | "targetArchiveHorizon": { 942 | "type": "string", 943 | "format": "uint64", 944 | "title": "Addresses less than this will be moved to the archive storage soon" 945 | } 946 | } 947 | }, 948 | "v5apiInfoParams": { 949 | "type": "object" 950 | }, 951 | "v5apiInfoResponse": { 952 | "type": "object", 953 | "properties": { 954 | "stat": { 955 | "$ref": "#/definitions/v5apiStatus" 956 | }, 957 | "mash": { 958 | "$ref": "#/definitions/v5apiMash" 959 | }, 960 | "majorVersion": { 961 | "type": "integer", 962 | "format": "int64" 963 | }, 964 | "minorVersion": { 965 | "type": "integer", 966 | "format": "int64" 967 | }, 968 | "build": { 969 | "type": "string" 970 | }, 971 | "proxy": { 972 | "$ref": "#/definitions/v5apiProxyInfo" 973 | } 974 | } 975 | }, 976 | "v5apiInsertParams": { 977 | "type": "object", 978 | "properties": { 979 | "uuid": { 980 | "type": "string", 981 | "format": "byte" 982 | }, 983 | "sync": { 984 | "type": "boolean", 985 | "format": "boolean" 986 | }, 987 | "merge_policy": { 988 | "$ref": "#/definitions/v5apiMergePolicy" 989 | }, 990 | "values": { 991 | "type": "array", 992 | "items": { 993 | "$ref": "#/definitions/v5apiRawPoint" 994 | } 995 | } 996 | } 997 | }, 998 | "v5apiInsertResponse": { 999 | "type": "object", 1000 | "properties": { 1001 | "stat": { 1002 | "$ref": "#/definitions/v5apiStatus" 1003 | }, 1004 | "versionMajor": { 1005 | "type": "string", 1006 | "format": "uint64" 1007 | }, 1008 | "versionMinor": { 1009 | "type": "string", 1010 | "format": "uint64" 1011 | } 1012 | } 1013 | }, 1014 | "v5apiKeyCount": { 1015 | "type": "object", 1016 | "properties": { 1017 | "key": { 1018 | "type": "string" 1019 | }, 1020 | "count": { 1021 | "type": "string", 1022 | "format": "uint64" 1023 | } 1024 | } 1025 | }, 1026 | "v5apiKeyOptValue": { 1027 | "type": "object", 1028 | "properties": { 1029 | "key": { 1030 | "type": "string" 1031 | }, 1032 | "val": { 1033 | "$ref": "#/definitions/v5apiOptValue" 1034 | } 1035 | } 1036 | }, 1037 | "v5apiListCollectionsParams": { 1038 | "type": "object", 1039 | "properties": { 1040 | "prefix": { 1041 | "type": "string" 1042 | }, 1043 | "role": { 1044 | "$ref": "#/definitions/v5apiRole" 1045 | } 1046 | } 1047 | }, 1048 | "v5apiListCollectionsResponse": { 1049 | "type": "object", 1050 | "properties": { 1051 | "stat": { 1052 | "$ref": "#/definitions/v5apiStatus" 1053 | }, 1054 | "collections": { 1055 | "type": "array", 1056 | "items": { 1057 | "type": "string" 1058 | } 1059 | } 1060 | } 1061 | }, 1062 | "v5apiLookupStreamsParams": { 1063 | "type": "object", 1064 | "properties": { 1065 | "collection": { 1066 | "type": "string" 1067 | }, 1068 | "isCollectionPrefix": { 1069 | "type": "boolean", 1070 | "format": "boolean" 1071 | }, 1072 | "tags": { 1073 | "type": "array", 1074 | "items": { 1075 | "$ref": "#/definitions/v5apiKeyOptValue" 1076 | } 1077 | }, 1078 | "annotations": { 1079 | "type": "array", 1080 | "items": { 1081 | "$ref": "#/definitions/v5apiKeyOptValue" 1082 | } 1083 | }, 1084 | "role": { 1085 | "$ref": "#/definitions/v5apiRole" 1086 | } 1087 | } 1088 | }, 1089 | "v5apiLookupStreamsResponse": { 1090 | "type": "object", 1091 | "properties": { 1092 | "stat": { 1093 | "$ref": "#/definitions/v5apiStatus" 1094 | }, 1095 | "results": { 1096 | "type": "array", 1097 | "items": { 1098 | "$ref": "#/definitions/v5apiStreamDescriptor" 1099 | } 1100 | } 1101 | } 1102 | }, 1103 | "v5apiMash": { 1104 | "type": "object", 1105 | "properties": { 1106 | "revision": { 1107 | "type": "string", 1108 | "format": "int64" 1109 | }, 1110 | "leader": { 1111 | "type": "string" 1112 | }, 1113 | "leaderRevision": { 1114 | "type": "string", 1115 | "format": "int64" 1116 | }, 1117 | "totalWeight": { 1118 | "type": "string", 1119 | "format": "int64" 1120 | }, 1121 | "healthy": { 1122 | "type": "boolean", 1123 | "format": "boolean" 1124 | }, 1125 | "unmapped": { 1126 | "type": "number", 1127 | "format": "double" 1128 | }, 1129 | "members": { 1130 | "type": "array", 1131 | "items": { 1132 | "$ref": "#/definitions/v5apiMember" 1133 | } 1134 | } 1135 | } 1136 | }, 1137 | "v5apiMember": { 1138 | "type": "object", 1139 | "properties": { 1140 | "hash": { 1141 | "type": "integer", 1142 | "format": "int64" 1143 | }, 1144 | "nodename": { 1145 | "type": "string" 1146 | }, 1147 | "up": { 1148 | "type": "boolean", 1149 | "format": "boolean" 1150 | }, 1151 | "in": { 1152 | "type": "boolean", 1153 | "format": "boolean" 1154 | }, 1155 | "enabled": { 1156 | "type": "boolean", 1157 | "format": "boolean" 1158 | }, 1159 | "start": { 1160 | "type": "string", 1161 | "format": "int64" 1162 | }, 1163 | "end": { 1164 | "type": "string", 1165 | "format": "int64" 1166 | }, 1167 | "weight": { 1168 | "type": "string", 1169 | "format": "int64" 1170 | }, 1171 | "readPreference": { 1172 | "type": "number", 1173 | "format": "double" 1174 | }, 1175 | "httpEndpoints": { 1176 | "type": "string" 1177 | }, 1178 | "grpcEndpoints": { 1179 | "type": "string" 1180 | } 1181 | } 1182 | }, 1183 | "v5apiMergePolicy": { 1184 | "type": "string", 1185 | "enum": [ 1186 | "NEVER", 1187 | "EQUAL", 1188 | "RETAIN", 1189 | "REPLACE" 1190 | ], 1191 | "default": "NEVER" 1192 | }, 1193 | "v5apiMetadataUsageParams": { 1194 | "type": "object", 1195 | "properties": { 1196 | "prefix": { 1197 | "type": "string" 1198 | }, 1199 | "role": { 1200 | "$ref": "#/definitions/v5apiRole" 1201 | } 1202 | } 1203 | }, 1204 | "v5apiMetadataUsageResponse": { 1205 | "type": "object", 1206 | "properties": { 1207 | "stat": { 1208 | "$ref": "#/definitions/v5apiStatus" 1209 | }, 1210 | "tags": { 1211 | "type": "array", 1212 | "items": { 1213 | "$ref": "#/definitions/v5apiKeyCount" 1214 | } 1215 | }, 1216 | "annotations": { 1217 | "type": "array", 1218 | "items": { 1219 | "$ref": "#/definitions/v5apiKeyCount" 1220 | } 1221 | } 1222 | } 1223 | }, 1224 | "v5apiNearestParams": { 1225 | "type": "object", 1226 | "properties": { 1227 | "uuid": { 1228 | "type": "string", 1229 | "format": "byte" 1230 | }, 1231 | "time": { 1232 | "type": "string", 1233 | "format": "int64" 1234 | }, 1235 | "versionMajor": { 1236 | "type": "string", 1237 | "format": "uint64" 1238 | }, 1239 | "backward": { 1240 | "type": "boolean", 1241 | "format": "boolean" 1242 | } 1243 | } 1244 | }, 1245 | "v5apiNearestResponse": { 1246 | "type": "object", 1247 | "properties": { 1248 | "stat": { 1249 | "$ref": "#/definitions/v5apiStatus" 1250 | }, 1251 | "versionMajor": { 1252 | "type": "string", 1253 | "format": "uint64" 1254 | }, 1255 | "versionMinor": { 1256 | "type": "string", 1257 | "format": "uint64" 1258 | }, 1259 | "value": { 1260 | "$ref": "#/definitions/v5apiRawPoint" 1261 | } 1262 | } 1263 | }, 1264 | "v5apiObliterateParams": { 1265 | "type": "object", 1266 | "properties": { 1267 | "uuid": { 1268 | "type": "string", 1269 | "format": "byte" 1270 | } 1271 | } 1272 | }, 1273 | "v5apiObliterateResponse": { 1274 | "type": "object", 1275 | "properties": { 1276 | "stat": { 1277 | "$ref": "#/definitions/v5apiStatus" 1278 | } 1279 | } 1280 | }, 1281 | "v5apiOptValue": { 1282 | "type": "object", 1283 | "properties": { 1284 | "value": { 1285 | "type": "string" 1286 | } 1287 | } 1288 | }, 1289 | "v5apiProxyInfo": { 1290 | "type": "object", 1291 | "properties": { 1292 | "proxyEndpoints": { 1293 | "type": "array", 1294 | "items": { 1295 | "type": "string" 1296 | } 1297 | } 1298 | } 1299 | }, 1300 | "v5apiRawPoint": { 1301 | "type": "object", 1302 | "properties": { 1303 | "time": { 1304 | "type": "string", 1305 | "format": "int64" 1306 | }, 1307 | "value": { 1308 | "type": "number", 1309 | "format": "double" 1310 | } 1311 | } 1312 | }, 1313 | "v5apiRawValuesParams": { 1314 | "type": "object", 1315 | "properties": { 1316 | "uuid": { 1317 | "type": "string", 1318 | "format": "byte" 1319 | }, 1320 | "start": { 1321 | "type": "string", 1322 | "format": "int64" 1323 | }, 1324 | "end": { 1325 | "type": "string", 1326 | "format": "int64" 1327 | }, 1328 | "versionMajor": { 1329 | "type": "string", 1330 | "format": "uint64" 1331 | } 1332 | } 1333 | }, 1334 | "v5apiRawValuesResponse": { 1335 | "type": "object", 1336 | "properties": { 1337 | "stat": { 1338 | "$ref": "#/definitions/v5apiStatus" 1339 | }, 1340 | "versionMajor": { 1341 | "type": "string", 1342 | "format": "uint64" 1343 | }, 1344 | "versionMinor": { 1345 | "type": "string", 1346 | "format": "uint64" 1347 | }, 1348 | "values": { 1349 | "type": "array", 1350 | "items": { 1351 | "$ref": "#/definitions/v5apiRawPoint" 1352 | } 1353 | } 1354 | } 1355 | }, 1356 | "v5apiReducedResolutionRange": { 1357 | "type": "object", 1358 | "properties": { 1359 | "Start": { 1360 | "type": "string", 1361 | "format": "int64" 1362 | }, 1363 | "End": { 1364 | "type": "string", 1365 | "format": "int64" 1366 | }, 1367 | "Resolution": { 1368 | "type": "integer", 1369 | "format": "int64" 1370 | } 1371 | } 1372 | }, 1373 | "v5apiRole": { 1374 | "type": "object", 1375 | "properties": { 1376 | "name": { 1377 | "type": "string" 1378 | } 1379 | } 1380 | }, 1381 | "v5apiSQLQueryParams": { 1382 | "type": "object", 1383 | "properties": { 1384 | "query": { 1385 | "type": "string" 1386 | }, 1387 | "params": { 1388 | "type": "array", 1389 | "items": { 1390 | "type": "string" 1391 | } 1392 | }, 1393 | "role": { 1394 | "$ref": "#/definitions/v5apiRole" 1395 | } 1396 | } 1397 | }, 1398 | "v5apiSQLQueryResponse": { 1399 | "type": "object", 1400 | "properties": { 1401 | "stat": { 1402 | "$ref": "#/definitions/v5apiStatus" 1403 | }, 1404 | "SQLQueryRow": { 1405 | "type": "array", 1406 | "items": { 1407 | "type": "string", 1408 | "format": "byte" 1409 | } 1410 | } 1411 | } 1412 | }, 1413 | "v5apiSetCompactionConfigParams": { 1414 | "type": "object", 1415 | "properties": { 1416 | "uuid": { 1417 | "type": "string", 1418 | "format": "byte", 1419 | "title": "Which stream to configure" 1420 | }, 1421 | "CompactedVersion": { 1422 | "type": "string", 1423 | "format": "uint64", 1424 | "title": "Accessing versions LESS than this is not allowed" 1425 | }, 1426 | "reducedResolutionRanges": { 1427 | "type": "array", 1428 | "items": { 1429 | "$ref": "#/definitions/v5apiReducedResolutionRange" 1430 | }, 1431 | "title": "For every timestamp \u003e= Start and \u003c End in this list,\nwe cannot traverse the tree \u003c Resolution.\nThese ranges are the new ones you want to add, not the full list" 1432 | }, 1433 | "targetArchiveHorizon": { 1434 | "type": "string", 1435 | "format": "uint64", 1436 | "title": "Addresses less than this will be moved to the archive storage soon\nYou can't set this to less than it is, so zero means leave as is" 1437 | } 1438 | } 1439 | }, 1440 | "v5apiSetCompactionConfigResponse": { 1441 | "type": "object", 1442 | "properties": { 1443 | "stat": { 1444 | "$ref": "#/definitions/v5apiStatus" 1445 | } 1446 | } 1447 | }, 1448 | "v5apiSetStreamAnnotationsParams": { 1449 | "type": "object", 1450 | "properties": { 1451 | "uuid": { 1452 | "type": "string", 1453 | "format": "byte" 1454 | }, 1455 | "expectedPropertyVersion": { 1456 | "type": "string", 1457 | "format": "uint64" 1458 | }, 1459 | "changes": { 1460 | "type": "array", 1461 | "items": { 1462 | "$ref": "#/definitions/v5apiKeyOptValue" 1463 | } 1464 | }, 1465 | "removals": { 1466 | "type": "array", 1467 | "items": { 1468 | "type": "string" 1469 | } 1470 | } 1471 | } 1472 | }, 1473 | "v5apiSetStreamAnnotationsResponse": { 1474 | "type": "object", 1475 | "properties": { 1476 | "stat": { 1477 | "$ref": "#/definitions/v5apiStatus" 1478 | } 1479 | } 1480 | }, 1481 | "v5apiSetStreamTagsParams": { 1482 | "type": "object", 1483 | "properties": { 1484 | "uuid": { 1485 | "type": "string", 1486 | "format": "byte" 1487 | }, 1488 | "expectedPropertyVersion": { 1489 | "type": "string", 1490 | "format": "uint64" 1491 | }, 1492 | "tags": { 1493 | "type": "array", 1494 | "items": { 1495 | "$ref": "#/definitions/v5apiKeyOptValue" 1496 | } 1497 | }, 1498 | "collection": { 1499 | "type": "string" 1500 | }, 1501 | "remove": { 1502 | "type": "array", 1503 | "items": { 1504 | "type": "string" 1505 | } 1506 | } 1507 | } 1508 | }, 1509 | "v5apiSetStreamTagsResponse": { 1510 | "type": "object", 1511 | "properties": { 1512 | "stat": { 1513 | "$ref": "#/definitions/v5apiStatus" 1514 | } 1515 | } 1516 | }, 1517 | "v5apiStatPoint": { 1518 | "type": "object", 1519 | "properties": { 1520 | "time": { 1521 | "type": "string", 1522 | "format": "int64" 1523 | }, 1524 | "min": { 1525 | "type": "number", 1526 | "format": "double" 1527 | }, 1528 | "mean": { 1529 | "type": "number", 1530 | "format": "double" 1531 | }, 1532 | "max": { 1533 | "type": "number", 1534 | "format": "double" 1535 | }, 1536 | "count": { 1537 | "type": "string", 1538 | "format": "uint64" 1539 | }, 1540 | "stddev": { 1541 | "type": "number", 1542 | "format": "double" 1543 | } 1544 | } 1545 | }, 1546 | "v5apiStatus": { 1547 | "type": "object", 1548 | "properties": { 1549 | "code": { 1550 | "type": "integer", 1551 | "format": "int64" 1552 | }, 1553 | "msg": { 1554 | "type": "string" 1555 | }, 1556 | "mash": { 1557 | "$ref": "#/definitions/v5apiMash" 1558 | } 1559 | } 1560 | }, 1561 | "v5apiStreamCSVConfig": { 1562 | "type": "object", 1563 | "properties": { 1564 | "version": { 1565 | "type": "string", 1566 | "format": "uint64" 1567 | }, 1568 | "label": { 1569 | "type": "string" 1570 | }, 1571 | "uuid": { 1572 | "type": "string", 1573 | "format": "byte" 1574 | } 1575 | } 1576 | }, 1577 | "v5apiStreamDescriptor": { 1578 | "type": "object", 1579 | "properties": { 1580 | "uuid": { 1581 | "type": "string", 1582 | "format": "byte" 1583 | }, 1584 | "collection": { 1585 | "type": "string" 1586 | }, 1587 | "tags": { 1588 | "type": "array", 1589 | "items": { 1590 | "$ref": "#/definitions/v5apiKeyOptValue" 1591 | } 1592 | }, 1593 | "annotations": { 1594 | "type": "array", 1595 | "items": { 1596 | "$ref": "#/definitions/v5apiKeyOptValue" 1597 | } 1598 | }, 1599 | "propertyVersion": { 1600 | "type": "string", 1601 | "format": "uint64" 1602 | } 1603 | } 1604 | }, 1605 | "v5apiStreamInfoParams": { 1606 | "type": "object", 1607 | "properties": { 1608 | "uuid": { 1609 | "type": "string", 1610 | "format": "byte" 1611 | }, 1612 | "omitVersion": { 1613 | "type": "boolean", 1614 | "format": "boolean" 1615 | }, 1616 | "omitDescriptor": { 1617 | "type": "boolean", 1618 | "format": "boolean" 1619 | }, 1620 | "role": { 1621 | "$ref": "#/definitions/v5apiRole" 1622 | } 1623 | } 1624 | }, 1625 | "v5apiStreamInfoResponse": { 1626 | "type": "object", 1627 | "properties": { 1628 | "stat": { 1629 | "$ref": "#/definitions/v5apiStatus" 1630 | }, 1631 | "versionMajor": { 1632 | "type": "string", 1633 | "format": "uint64" 1634 | }, 1635 | "versionMinor": { 1636 | "type": "string", 1637 | "format": "uint64" 1638 | }, 1639 | "descriptor": { 1640 | "$ref": "#/definitions/v5apiStreamDescriptor" 1641 | } 1642 | } 1643 | }, 1644 | "v5apiWindowsParams": { 1645 | "type": "object", 1646 | "properties": { 1647 | "uuid": { 1648 | "type": "string", 1649 | "format": "byte" 1650 | }, 1651 | "start": { 1652 | "type": "string", 1653 | "format": "int64" 1654 | }, 1655 | "end": { 1656 | "type": "string", 1657 | "format": "int64" 1658 | }, 1659 | "versionMajor": { 1660 | "type": "string", 1661 | "format": "uint64" 1662 | }, 1663 | "width": { 1664 | "type": "string", 1665 | "format": "uint64" 1666 | }, 1667 | "depth": { 1668 | "type": "integer", 1669 | "format": "int64" 1670 | } 1671 | } 1672 | }, 1673 | "v5apiWindowsResponse": { 1674 | "type": "object", 1675 | "properties": { 1676 | "stat": { 1677 | "$ref": "#/definitions/v5apiStatus" 1678 | }, 1679 | "versionMajor": { 1680 | "type": "string", 1681 | "format": "uint64" 1682 | }, 1683 | "versionMinor": { 1684 | "type": "string", 1685 | "format": "uint64" 1686 | }, 1687 | "values": { 1688 | "type": "array", 1689 | "items": { 1690 | "$ref": "#/definitions/v5apiStatPoint" 1691 | } 1692 | } 1693 | } 1694 | } 1695 | }, 1696 | "x-stream-definitions": { 1697 | "v5apiAlignedWindowsResponse": { 1698 | "type": "object", 1699 | "properties": { 1700 | "result": { 1701 | "$ref": "#/definitions/v5apiAlignedWindowsResponse" 1702 | }, 1703 | "error": { 1704 | "$ref": "#/definitions/runtimeStreamError" 1705 | } 1706 | }, 1707 | "title": "Stream result of v5apiAlignedWindowsResponse" 1708 | }, 1709 | "v5apiChangesResponse": { 1710 | "type": "object", 1711 | "properties": { 1712 | "result": { 1713 | "$ref": "#/definitions/v5apiChangesResponse" 1714 | }, 1715 | "error": { 1716 | "$ref": "#/definitions/runtimeStreamError" 1717 | } 1718 | }, 1719 | "title": "Stream result of v5apiChangesResponse" 1720 | }, 1721 | "v5apiGenerateCSVResponse": { 1722 | "type": "object", 1723 | "properties": { 1724 | "result": { 1725 | "$ref": "#/definitions/v5apiGenerateCSVResponse" 1726 | }, 1727 | "error": { 1728 | "$ref": "#/definitions/runtimeStreamError" 1729 | } 1730 | }, 1731 | "title": "Stream result of v5apiGenerateCSVResponse" 1732 | }, 1733 | "v5apiListCollectionsResponse": { 1734 | "type": "object", 1735 | "properties": { 1736 | "result": { 1737 | "$ref": "#/definitions/v5apiListCollectionsResponse" 1738 | }, 1739 | "error": { 1740 | "$ref": "#/definitions/runtimeStreamError" 1741 | } 1742 | }, 1743 | "title": "Stream result of v5apiListCollectionsResponse" 1744 | }, 1745 | "v5apiLookupStreamsResponse": { 1746 | "type": "object", 1747 | "properties": { 1748 | "result": { 1749 | "$ref": "#/definitions/v5apiLookupStreamsResponse" 1750 | }, 1751 | "error": { 1752 | "$ref": "#/definitions/runtimeStreamError" 1753 | } 1754 | }, 1755 | "title": "Stream result of v5apiLookupStreamsResponse" 1756 | }, 1757 | "v5apiRawValuesResponse": { 1758 | "type": "object", 1759 | "properties": { 1760 | "result": { 1761 | "$ref": "#/definitions/v5apiRawValuesResponse" 1762 | }, 1763 | "error": { 1764 | "$ref": "#/definitions/runtimeStreamError" 1765 | } 1766 | }, 1767 | "title": "Stream result of v5apiRawValuesResponse" 1768 | }, 1769 | "v5apiSQLQueryResponse": { 1770 | "type": "object", 1771 | "properties": { 1772 | "result": { 1773 | "$ref": "#/definitions/v5apiSQLQueryResponse" 1774 | }, 1775 | "error": { 1776 | "$ref": "#/definitions/runtimeStreamError" 1777 | } 1778 | }, 1779 | "title": "Stream result of v5apiSQLQueryResponse" 1780 | }, 1781 | "v5apiWindowsResponse": { 1782 | "type": "object", 1783 | "properties": { 1784 | "result": { 1785 | "$ref": "#/definitions/v5apiWindowsResponse" 1786 | }, 1787 | "error": { 1788 | "$ref": "#/definitions/runtimeStreamError" 1789 | } 1790 | }, 1791 | "title": "Stream result of v5apiWindowsResponse" 1792 | } 1793 | } 1794 | } 1795 | -------------------------------------------------------------------------------- /v5api/btrdb_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | 3 | package v5api 4 | 5 | import ( 6 | context "context" 7 | grpc "google.golang.org/grpc" 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | // This is a compile-time assertion to ensure that this generated file 13 | // is compatible with the grpc package it is being compiled against. 14 | // Requires gRPC-Go v1.32.0 or later. 15 | const _ = grpc.SupportPackageIsVersion7 16 | 17 | // BTrDBClient is the client API for BTrDB service. 18 | // 19 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 20 | type BTrDBClient interface { 21 | RawValues(ctx context.Context, in *RawValuesParams, opts ...grpc.CallOption) (BTrDB_RawValuesClient, error) 22 | MultiRawValues(ctx context.Context, in *MultiRawValuesParams, opts ...grpc.CallOption) (BTrDB_MultiRawValuesClient, error) 23 | AlignedWindows(ctx context.Context, in *AlignedWindowsParams, opts ...grpc.CallOption) (BTrDB_AlignedWindowsClient, error) 24 | Windows(ctx context.Context, in *WindowsParams, opts ...grpc.CallOption) (BTrDB_WindowsClient, error) 25 | StreamInfo(ctx context.Context, in *StreamInfoParams, opts ...grpc.CallOption) (*StreamInfoResponse, error) 26 | SetStreamAnnotations(ctx context.Context, in *SetStreamAnnotationsParams, opts ...grpc.CallOption) (*SetStreamAnnotationsResponse, error) 27 | SetStreamTags(ctx context.Context, in *SetStreamTagsParams, opts ...grpc.CallOption) (*SetStreamTagsResponse, error) 28 | Create(ctx context.Context, in *CreateParams, opts ...grpc.CallOption) (*CreateResponse, error) 29 | ListCollections(ctx context.Context, in *ListCollectionsParams, opts ...grpc.CallOption) (BTrDB_ListCollectionsClient, error) 30 | LookupStreams(ctx context.Context, in *LookupStreamsParams, opts ...grpc.CallOption) (BTrDB_LookupStreamsClient, error) 31 | Nearest(ctx context.Context, in *NearestParams, opts ...grpc.CallOption) (*NearestResponse, error) 32 | Changes(ctx context.Context, in *ChangesParams, opts ...grpc.CallOption) (BTrDB_ChangesClient, error) 33 | Insert(ctx context.Context, in *InsertParams, opts ...grpc.CallOption) (*InsertResponse, error) 34 | Delete(ctx context.Context, in *DeleteParams, opts ...grpc.CallOption) (*DeleteResponse, error) 35 | Info(ctx context.Context, in *InfoParams, opts ...grpc.CallOption) (*InfoResponse, error) 36 | FaultInject(ctx context.Context, in *FaultInjectParams, opts ...grpc.CallOption) (*FaultInjectResponse, error) 37 | Flush(ctx context.Context, in *FlushParams, opts ...grpc.CallOption) (*FlushResponse, error) 38 | Obliterate(ctx context.Context, in *ObliterateParams, opts ...grpc.CallOption) (*ObliterateResponse, error) 39 | GetMetadataUsage(ctx context.Context, in *MetadataUsageParams, opts ...grpc.CallOption) (*MetadataUsageResponse, error) 40 | GenerateCSV(ctx context.Context, in *GenerateCSVParams, opts ...grpc.CallOption) (BTrDB_GenerateCSVClient, error) 41 | SQLQuery(ctx context.Context, in *SQLQueryParams, opts ...grpc.CallOption) (BTrDB_SQLQueryClient, error) 42 | Subscribe(ctx context.Context, in *SubscriptionParams, opts ...grpc.CallOption) (BTrDB_SubscribeClient, error) 43 | SetCompactionConfig(ctx context.Context, in *SetCompactionConfigParams, opts ...grpc.CallOption) (*SetCompactionConfigResponse, error) 44 | GetCompactionConfig(ctx context.Context, in *GetCompactionConfigParams, opts ...grpc.CallOption) (*GetCompactionConfigResponse, error) 45 | } 46 | 47 | type bTrDBClient struct { 48 | cc grpc.ClientConnInterface 49 | } 50 | 51 | func NewBTrDBClient(cc grpc.ClientConnInterface) BTrDBClient { 52 | return &bTrDBClient{cc} 53 | } 54 | 55 | func (c *bTrDBClient) RawValues(ctx context.Context, in *RawValuesParams, opts ...grpc.CallOption) (BTrDB_RawValuesClient, error) { 56 | stream, err := c.cc.NewStream(ctx, &BTrDB_ServiceDesc.Streams[0], "/v5api.BTrDB/RawValues", opts...) 57 | if err != nil { 58 | return nil, err 59 | } 60 | x := &bTrDBRawValuesClient{stream} 61 | if err := x.ClientStream.SendMsg(in); err != nil { 62 | return nil, err 63 | } 64 | if err := x.ClientStream.CloseSend(); err != nil { 65 | return nil, err 66 | } 67 | return x, nil 68 | } 69 | 70 | type BTrDB_RawValuesClient interface { 71 | Recv() (*RawValuesResponse, error) 72 | grpc.ClientStream 73 | } 74 | 75 | type bTrDBRawValuesClient struct { 76 | grpc.ClientStream 77 | } 78 | 79 | func (x *bTrDBRawValuesClient) Recv() (*RawValuesResponse, error) { 80 | m := new(RawValuesResponse) 81 | if err := x.ClientStream.RecvMsg(m); err != nil { 82 | return nil, err 83 | } 84 | return m, nil 85 | } 86 | 87 | func (c *bTrDBClient) MultiRawValues(ctx context.Context, in *MultiRawValuesParams, opts ...grpc.CallOption) (BTrDB_MultiRawValuesClient, error) { 88 | stream, err := c.cc.NewStream(ctx, &BTrDB_ServiceDesc.Streams[1], "/v5api.BTrDB/MultiRawValues", opts...) 89 | if err != nil { 90 | return nil, err 91 | } 92 | x := &bTrDBMultiRawValuesClient{stream} 93 | if err := x.ClientStream.SendMsg(in); err != nil { 94 | return nil, err 95 | } 96 | if err := x.ClientStream.CloseSend(); err != nil { 97 | return nil, err 98 | } 99 | return x, nil 100 | } 101 | 102 | type BTrDB_MultiRawValuesClient interface { 103 | Recv() (*MultiRawValuesResponse, error) 104 | grpc.ClientStream 105 | } 106 | 107 | type bTrDBMultiRawValuesClient struct { 108 | grpc.ClientStream 109 | } 110 | 111 | func (x *bTrDBMultiRawValuesClient) Recv() (*MultiRawValuesResponse, error) { 112 | m := new(MultiRawValuesResponse) 113 | if err := x.ClientStream.RecvMsg(m); err != nil { 114 | return nil, err 115 | } 116 | return m, nil 117 | } 118 | 119 | func (c *bTrDBClient) AlignedWindows(ctx context.Context, in *AlignedWindowsParams, opts ...grpc.CallOption) (BTrDB_AlignedWindowsClient, error) { 120 | stream, err := c.cc.NewStream(ctx, &BTrDB_ServiceDesc.Streams[2], "/v5api.BTrDB/AlignedWindows", opts...) 121 | if err != nil { 122 | return nil, err 123 | } 124 | x := &bTrDBAlignedWindowsClient{stream} 125 | if err := x.ClientStream.SendMsg(in); err != nil { 126 | return nil, err 127 | } 128 | if err := x.ClientStream.CloseSend(); err != nil { 129 | return nil, err 130 | } 131 | return x, nil 132 | } 133 | 134 | type BTrDB_AlignedWindowsClient interface { 135 | Recv() (*AlignedWindowsResponse, error) 136 | grpc.ClientStream 137 | } 138 | 139 | type bTrDBAlignedWindowsClient struct { 140 | grpc.ClientStream 141 | } 142 | 143 | func (x *bTrDBAlignedWindowsClient) Recv() (*AlignedWindowsResponse, error) { 144 | m := new(AlignedWindowsResponse) 145 | if err := x.ClientStream.RecvMsg(m); err != nil { 146 | return nil, err 147 | } 148 | return m, nil 149 | } 150 | 151 | func (c *bTrDBClient) Windows(ctx context.Context, in *WindowsParams, opts ...grpc.CallOption) (BTrDB_WindowsClient, error) { 152 | stream, err := c.cc.NewStream(ctx, &BTrDB_ServiceDesc.Streams[3], "/v5api.BTrDB/Windows", opts...) 153 | if err != nil { 154 | return nil, err 155 | } 156 | x := &bTrDBWindowsClient{stream} 157 | if err := x.ClientStream.SendMsg(in); err != nil { 158 | return nil, err 159 | } 160 | if err := x.ClientStream.CloseSend(); err != nil { 161 | return nil, err 162 | } 163 | return x, nil 164 | } 165 | 166 | type BTrDB_WindowsClient interface { 167 | Recv() (*WindowsResponse, error) 168 | grpc.ClientStream 169 | } 170 | 171 | type bTrDBWindowsClient struct { 172 | grpc.ClientStream 173 | } 174 | 175 | func (x *bTrDBWindowsClient) Recv() (*WindowsResponse, error) { 176 | m := new(WindowsResponse) 177 | if err := x.ClientStream.RecvMsg(m); err != nil { 178 | return nil, err 179 | } 180 | return m, nil 181 | } 182 | 183 | func (c *bTrDBClient) StreamInfo(ctx context.Context, in *StreamInfoParams, opts ...grpc.CallOption) (*StreamInfoResponse, error) { 184 | out := new(StreamInfoResponse) 185 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/StreamInfo", in, out, opts...) 186 | if err != nil { 187 | return nil, err 188 | } 189 | return out, nil 190 | } 191 | 192 | func (c *bTrDBClient) SetStreamAnnotations(ctx context.Context, in *SetStreamAnnotationsParams, opts ...grpc.CallOption) (*SetStreamAnnotationsResponse, error) { 193 | out := new(SetStreamAnnotationsResponse) 194 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/SetStreamAnnotations", in, out, opts...) 195 | if err != nil { 196 | return nil, err 197 | } 198 | return out, nil 199 | } 200 | 201 | func (c *bTrDBClient) SetStreamTags(ctx context.Context, in *SetStreamTagsParams, opts ...grpc.CallOption) (*SetStreamTagsResponse, error) { 202 | out := new(SetStreamTagsResponse) 203 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/SetStreamTags", in, out, opts...) 204 | if err != nil { 205 | return nil, err 206 | } 207 | return out, nil 208 | } 209 | 210 | func (c *bTrDBClient) Create(ctx context.Context, in *CreateParams, opts ...grpc.CallOption) (*CreateResponse, error) { 211 | out := new(CreateResponse) 212 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/Create", in, out, opts...) 213 | if err != nil { 214 | return nil, err 215 | } 216 | return out, nil 217 | } 218 | 219 | func (c *bTrDBClient) ListCollections(ctx context.Context, in *ListCollectionsParams, opts ...grpc.CallOption) (BTrDB_ListCollectionsClient, error) { 220 | stream, err := c.cc.NewStream(ctx, &BTrDB_ServiceDesc.Streams[4], "/v5api.BTrDB/ListCollections", opts...) 221 | if err != nil { 222 | return nil, err 223 | } 224 | x := &bTrDBListCollectionsClient{stream} 225 | if err := x.ClientStream.SendMsg(in); err != nil { 226 | return nil, err 227 | } 228 | if err := x.ClientStream.CloseSend(); err != nil { 229 | return nil, err 230 | } 231 | return x, nil 232 | } 233 | 234 | type BTrDB_ListCollectionsClient interface { 235 | Recv() (*ListCollectionsResponse, error) 236 | grpc.ClientStream 237 | } 238 | 239 | type bTrDBListCollectionsClient struct { 240 | grpc.ClientStream 241 | } 242 | 243 | func (x *bTrDBListCollectionsClient) Recv() (*ListCollectionsResponse, error) { 244 | m := new(ListCollectionsResponse) 245 | if err := x.ClientStream.RecvMsg(m); err != nil { 246 | return nil, err 247 | } 248 | return m, nil 249 | } 250 | 251 | func (c *bTrDBClient) LookupStreams(ctx context.Context, in *LookupStreamsParams, opts ...grpc.CallOption) (BTrDB_LookupStreamsClient, error) { 252 | stream, err := c.cc.NewStream(ctx, &BTrDB_ServiceDesc.Streams[5], "/v5api.BTrDB/LookupStreams", opts...) 253 | if err != nil { 254 | return nil, err 255 | } 256 | x := &bTrDBLookupStreamsClient{stream} 257 | if err := x.ClientStream.SendMsg(in); err != nil { 258 | return nil, err 259 | } 260 | if err := x.ClientStream.CloseSend(); err != nil { 261 | return nil, err 262 | } 263 | return x, nil 264 | } 265 | 266 | type BTrDB_LookupStreamsClient interface { 267 | Recv() (*LookupStreamsResponse, error) 268 | grpc.ClientStream 269 | } 270 | 271 | type bTrDBLookupStreamsClient struct { 272 | grpc.ClientStream 273 | } 274 | 275 | func (x *bTrDBLookupStreamsClient) Recv() (*LookupStreamsResponse, error) { 276 | m := new(LookupStreamsResponse) 277 | if err := x.ClientStream.RecvMsg(m); err != nil { 278 | return nil, err 279 | } 280 | return m, nil 281 | } 282 | 283 | func (c *bTrDBClient) Nearest(ctx context.Context, in *NearestParams, opts ...grpc.CallOption) (*NearestResponse, error) { 284 | out := new(NearestResponse) 285 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/Nearest", in, out, opts...) 286 | if err != nil { 287 | return nil, err 288 | } 289 | return out, nil 290 | } 291 | 292 | func (c *bTrDBClient) Changes(ctx context.Context, in *ChangesParams, opts ...grpc.CallOption) (BTrDB_ChangesClient, error) { 293 | stream, err := c.cc.NewStream(ctx, &BTrDB_ServiceDesc.Streams[6], "/v5api.BTrDB/Changes", opts...) 294 | if err != nil { 295 | return nil, err 296 | } 297 | x := &bTrDBChangesClient{stream} 298 | if err := x.ClientStream.SendMsg(in); err != nil { 299 | return nil, err 300 | } 301 | if err := x.ClientStream.CloseSend(); err != nil { 302 | return nil, err 303 | } 304 | return x, nil 305 | } 306 | 307 | type BTrDB_ChangesClient interface { 308 | Recv() (*ChangesResponse, error) 309 | grpc.ClientStream 310 | } 311 | 312 | type bTrDBChangesClient struct { 313 | grpc.ClientStream 314 | } 315 | 316 | func (x *bTrDBChangesClient) Recv() (*ChangesResponse, error) { 317 | m := new(ChangesResponse) 318 | if err := x.ClientStream.RecvMsg(m); err != nil { 319 | return nil, err 320 | } 321 | return m, nil 322 | } 323 | 324 | func (c *bTrDBClient) Insert(ctx context.Context, in *InsertParams, opts ...grpc.CallOption) (*InsertResponse, error) { 325 | out := new(InsertResponse) 326 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/Insert", in, out, opts...) 327 | if err != nil { 328 | return nil, err 329 | } 330 | return out, nil 331 | } 332 | 333 | func (c *bTrDBClient) Delete(ctx context.Context, in *DeleteParams, opts ...grpc.CallOption) (*DeleteResponse, error) { 334 | out := new(DeleteResponse) 335 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/Delete", in, out, opts...) 336 | if err != nil { 337 | return nil, err 338 | } 339 | return out, nil 340 | } 341 | 342 | func (c *bTrDBClient) Info(ctx context.Context, in *InfoParams, opts ...grpc.CallOption) (*InfoResponse, error) { 343 | out := new(InfoResponse) 344 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/Info", in, out, opts...) 345 | if err != nil { 346 | return nil, err 347 | } 348 | return out, nil 349 | } 350 | 351 | func (c *bTrDBClient) FaultInject(ctx context.Context, in *FaultInjectParams, opts ...grpc.CallOption) (*FaultInjectResponse, error) { 352 | out := new(FaultInjectResponse) 353 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/FaultInject", in, out, opts...) 354 | if err != nil { 355 | return nil, err 356 | } 357 | return out, nil 358 | } 359 | 360 | func (c *bTrDBClient) Flush(ctx context.Context, in *FlushParams, opts ...grpc.CallOption) (*FlushResponse, error) { 361 | out := new(FlushResponse) 362 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/Flush", in, out, opts...) 363 | if err != nil { 364 | return nil, err 365 | } 366 | return out, nil 367 | } 368 | 369 | func (c *bTrDBClient) Obliterate(ctx context.Context, in *ObliterateParams, opts ...grpc.CallOption) (*ObliterateResponse, error) { 370 | out := new(ObliterateResponse) 371 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/Obliterate", in, out, opts...) 372 | if err != nil { 373 | return nil, err 374 | } 375 | return out, nil 376 | } 377 | 378 | func (c *bTrDBClient) GetMetadataUsage(ctx context.Context, in *MetadataUsageParams, opts ...grpc.CallOption) (*MetadataUsageResponse, error) { 379 | out := new(MetadataUsageResponse) 380 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/GetMetadataUsage", in, out, opts...) 381 | if err != nil { 382 | return nil, err 383 | } 384 | return out, nil 385 | } 386 | 387 | func (c *bTrDBClient) GenerateCSV(ctx context.Context, in *GenerateCSVParams, opts ...grpc.CallOption) (BTrDB_GenerateCSVClient, error) { 388 | stream, err := c.cc.NewStream(ctx, &BTrDB_ServiceDesc.Streams[7], "/v5api.BTrDB/GenerateCSV", opts...) 389 | if err != nil { 390 | return nil, err 391 | } 392 | x := &bTrDBGenerateCSVClient{stream} 393 | if err := x.ClientStream.SendMsg(in); err != nil { 394 | return nil, err 395 | } 396 | if err := x.ClientStream.CloseSend(); err != nil { 397 | return nil, err 398 | } 399 | return x, nil 400 | } 401 | 402 | type BTrDB_GenerateCSVClient interface { 403 | Recv() (*GenerateCSVResponse, error) 404 | grpc.ClientStream 405 | } 406 | 407 | type bTrDBGenerateCSVClient struct { 408 | grpc.ClientStream 409 | } 410 | 411 | func (x *bTrDBGenerateCSVClient) Recv() (*GenerateCSVResponse, error) { 412 | m := new(GenerateCSVResponse) 413 | if err := x.ClientStream.RecvMsg(m); err != nil { 414 | return nil, err 415 | } 416 | return m, nil 417 | } 418 | 419 | func (c *bTrDBClient) SQLQuery(ctx context.Context, in *SQLQueryParams, opts ...grpc.CallOption) (BTrDB_SQLQueryClient, error) { 420 | stream, err := c.cc.NewStream(ctx, &BTrDB_ServiceDesc.Streams[8], "/v5api.BTrDB/SQLQuery", opts...) 421 | if err != nil { 422 | return nil, err 423 | } 424 | x := &bTrDBSQLQueryClient{stream} 425 | if err := x.ClientStream.SendMsg(in); err != nil { 426 | return nil, err 427 | } 428 | if err := x.ClientStream.CloseSend(); err != nil { 429 | return nil, err 430 | } 431 | return x, nil 432 | } 433 | 434 | type BTrDB_SQLQueryClient interface { 435 | Recv() (*SQLQueryResponse, error) 436 | grpc.ClientStream 437 | } 438 | 439 | type bTrDBSQLQueryClient struct { 440 | grpc.ClientStream 441 | } 442 | 443 | func (x *bTrDBSQLQueryClient) Recv() (*SQLQueryResponse, error) { 444 | m := new(SQLQueryResponse) 445 | if err := x.ClientStream.RecvMsg(m); err != nil { 446 | return nil, err 447 | } 448 | return m, nil 449 | } 450 | 451 | func (c *bTrDBClient) Subscribe(ctx context.Context, in *SubscriptionParams, opts ...grpc.CallOption) (BTrDB_SubscribeClient, error) { 452 | stream, err := c.cc.NewStream(ctx, &BTrDB_ServiceDesc.Streams[9], "/v5api.BTrDB/Subscribe", opts...) 453 | if err != nil { 454 | return nil, err 455 | } 456 | x := &bTrDBSubscribeClient{stream} 457 | if err := x.ClientStream.SendMsg(in); err != nil { 458 | return nil, err 459 | } 460 | if err := x.ClientStream.CloseSend(); err != nil { 461 | return nil, err 462 | } 463 | return x, nil 464 | } 465 | 466 | type BTrDB_SubscribeClient interface { 467 | Recv() (*SubscriptionResp, error) 468 | grpc.ClientStream 469 | } 470 | 471 | type bTrDBSubscribeClient struct { 472 | grpc.ClientStream 473 | } 474 | 475 | func (x *bTrDBSubscribeClient) Recv() (*SubscriptionResp, error) { 476 | m := new(SubscriptionResp) 477 | if err := x.ClientStream.RecvMsg(m); err != nil { 478 | return nil, err 479 | } 480 | return m, nil 481 | } 482 | 483 | func (c *bTrDBClient) SetCompactionConfig(ctx context.Context, in *SetCompactionConfigParams, opts ...grpc.CallOption) (*SetCompactionConfigResponse, error) { 484 | out := new(SetCompactionConfigResponse) 485 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/SetCompactionConfig", in, out, opts...) 486 | if err != nil { 487 | return nil, err 488 | } 489 | return out, nil 490 | } 491 | 492 | func (c *bTrDBClient) GetCompactionConfig(ctx context.Context, in *GetCompactionConfigParams, opts ...grpc.CallOption) (*GetCompactionConfigResponse, error) { 493 | out := new(GetCompactionConfigResponse) 494 | err := c.cc.Invoke(ctx, "/v5api.BTrDB/GetCompactionConfig", in, out, opts...) 495 | if err != nil { 496 | return nil, err 497 | } 498 | return out, nil 499 | } 500 | 501 | // BTrDBServer is the server API for BTrDB service. 502 | // All implementations must embed UnimplementedBTrDBServer 503 | // for forward compatibility 504 | type BTrDBServer interface { 505 | RawValues(*RawValuesParams, BTrDB_RawValuesServer) error 506 | MultiRawValues(*MultiRawValuesParams, BTrDB_MultiRawValuesServer) error 507 | AlignedWindows(*AlignedWindowsParams, BTrDB_AlignedWindowsServer) error 508 | Windows(*WindowsParams, BTrDB_WindowsServer) error 509 | StreamInfo(context.Context, *StreamInfoParams) (*StreamInfoResponse, error) 510 | SetStreamAnnotations(context.Context, *SetStreamAnnotationsParams) (*SetStreamAnnotationsResponse, error) 511 | SetStreamTags(context.Context, *SetStreamTagsParams) (*SetStreamTagsResponse, error) 512 | Create(context.Context, *CreateParams) (*CreateResponse, error) 513 | ListCollections(*ListCollectionsParams, BTrDB_ListCollectionsServer) error 514 | LookupStreams(*LookupStreamsParams, BTrDB_LookupStreamsServer) error 515 | Nearest(context.Context, *NearestParams) (*NearestResponse, error) 516 | Changes(*ChangesParams, BTrDB_ChangesServer) error 517 | Insert(context.Context, *InsertParams) (*InsertResponse, error) 518 | Delete(context.Context, *DeleteParams) (*DeleteResponse, error) 519 | Info(context.Context, *InfoParams) (*InfoResponse, error) 520 | FaultInject(context.Context, *FaultInjectParams) (*FaultInjectResponse, error) 521 | Flush(context.Context, *FlushParams) (*FlushResponse, error) 522 | Obliterate(context.Context, *ObliterateParams) (*ObliterateResponse, error) 523 | GetMetadataUsage(context.Context, *MetadataUsageParams) (*MetadataUsageResponse, error) 524 | GenerateCSV(*GenerateCSVParams, BTrDB_GenerateCSVServer) error 525 | SQLQuery(*SQLQueryParams, BTrDB_SQLQueryServer) error 526 | Subscribe(*SubscriptionParams, BTrDB_SubscribeServer) error 527 | SetCompactionConfig(context.Context, *SetCompactionConfigParams) (*SetCompactionConfigResponse, error) 528 | GetCompactionConfig(context.Context, *GetCompactionConfigParams) (*GetCompactionConfigResponse, error) 529 | mustEmbedUnimplementedBTrDBServer() 530 | } 531 | 532 | // UnimplementedBTrDBServer must be embedded to have forward compatible implementations. 533 | type UnimplementedBTrDBServer struct { 534 | } 535 | 536 | func (UnimplementedBTrDBServer) RawValues(*RawValuesParams, BTrDB_RawValuesServer) error { 537 | return status.Errorf(codes.Unimplemented, "method RawValues not implemented") 538 | } 539 | func (UnimplementedBTrDBServer) MultiRawValues(*MultiRawValuesParams, BTrDB_MultiRawValuesServer) error { 540 | return status.Errorf(codes.Unimplemented, "method MultiRawValues not implemented") 541 | } 542 | func (UnimplementedBTrDBServer) AlignedWindows(*AlignedWindowsParams, BTrDB_AlignedWindowsServer) error { 543 | return status.Errorf(codes.Unimplemented, "method AlignedWindows not implemented") 544 | } 545 | func (UnimplementedBTrDBServer) Windows(*WindowsParams, BTrDB_WindowsServer) error { 546 | return status.Errorf(codes.Unimplemented, "method Windows not implemented") 547 | } 548 | func (UnimplementedBTrDBServer) StreamInfo(context.Context, *StreamInfoParams) (*StreamInfoResponse, error) { 549 | return nil, status.Errorf(codes.Unimplemented, "method StreamInfo not implemented") 550 | } 551 | func (UnimplementedBTrDBServer) SetStreamAnnotations(context.Context, *SetStreamAnnotationsParams) (*SetStreamAnnotationsResponse, error) { 552 | return nil, status.Errorf(codes.Unimplemented, "method SetStreamAnnotations not implemented") 553 | } 554 | func (UnimplementedBTrDBServer) SetStreamTags(context.Context, *SetStreamTagsParams) (*SetStreamTagsResponse, error) { 555 | return nil, status.Errorf(codes.Unimplemented, "method SetStreamTags not implemented") 556 | } 557 | func (UnimplementedBTrDBServer) Create(context.Context, *CreateParams) (*CreateResponse, error) { 558 | return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") 559 | } 560 | func (UnimplementedBTrDBServer) ListCollections(*ListCollectionsParams, BTrDB_ListCollectionsServer) error { 561 | return status.Errorf(codes.Unimplemented, "method ListCollections not implemented") 562 | } 563 | func (UnimplementedBTrDBServer) LookupStreams(*LookupStreamsParams, BTrDB_LookupStreamsServer) error { 564 | return status.Errorf(codes.Unimplemented, "method LookupStreams not implemented") 565 | } 566 | func (UnimplementedBTrDBServer) Nearest(context.Context, *NearestParams) (*NearestResponse, error) { 567 | return nil, status.Errorf(codes.Unimplemented, "method Nearest not implemented") 568 | } 569 | func (UnimplementedBTrDBServer) Changes(*ChangesParams, BTrDB_ChangesServer) error { 570 | return status.Errorf(codes.Unimplemented, "method Changes not implemented") 571 | } 572 | func (UnimplementedBTrDBServer) Insert(context.Context, *InsertParams) (*InsertResponse, error) { 573 | return nil, status.Errorf(codes.Unimplemented, "method Insert not implemented") 574 | } 575 | func (UnimplementedBTrDBServer) Delete(context.Context, *DeleteParams) (*DeleteResponse, error) { 576 | return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") 577 | } 578 | func (UnimplementedBTrDBServer) Info(context.Context, *InfoParams) (*InfoResponse, error) { 579 | return nil, status.Errorf(codes.Unimplemented, "method Info not implemented") 580 | } 581 | func (UnimplementedBTrDBServer) FaultInject(context.Context, *FaultInjectParams) (*FaultInjectResponse, error) { 582 | return nil, status.Errorf(codes.Unimplemented, "method FaultInject not implemented") 583 | } 584 | func (UnimplementedBTrDBServer) Flush(context.Context, *FlushParams) (*FlushResponse, error) { 585 | return nil, status.Errorf(codes.Unimplemented, "method Flush not implemented") 586 | } 587 | func (UnimplementedBTrDBServer) Obliterate(context.Context, *ObliterateParams) (*ObliterateResponse, error) { 588 | return nil, status.Errorf(codes.Unimplemented, "method Obliterate not implemented") 589 | } 590 | func (UnimplementedBTrDBServer) GetMetadataUsage(context.Context, *MetadataUsageParams) (*MetadataUsageResponse, error) { 591 | return nil, status.Errorf(codes.Unimplemented, "method GetMetadataUsage not implemented") 592 | } 593 | func (UnimplementedBTrDBServer) GenerateCSV(*GenerateCSVParams, BTrDB_GenerateCSVServer) error { 594 | return status.Errorf(codes.Unimplemented, "method GenerateCSV not implemented") 595 | } 596 | func (UnimplementedBTrDBServer) SQLQuery(*SQLQueryParams, BTrDB_SQLQueryServer) error { 597 | return status.Errorf(codes.Unimplemented, "method SQLQuery not implemented") 598 | } 599 | func (UnimplementedBTrDBServer) Subscribe(*SubscriptionParams, BTrDB_SubscribeServer) error { 600 | return status.Errorf(codes.Unimplemented, "method Subscribe not implemented") 601 | } 602 | func (UnimplementedBTrDBServer) SetCompactionConfig(context.Context, *SetCompactionConfigParams) (*SetCompactionConfigResponse, error) { 603 | return nil, status.Errorf(codes.Unimplemented, "method SetCompactionConfig not implemented") 604 | } 605 | func (UnimplementedBTrDBServer) GetCompactionConfig(context.Context, *GetCompactionConfigParams) (*GetCompactionConfigResponse, error) { 606 | return nil, status.Errorf(codes.Unimplemented, "method GetCompactionConfig not implemented") 607 | } 608 | func (UnimplementedBTrDBServer) mustEmbedUnimplementedBTrDBServer() {} 609 | 610 | // UnsafeBTrDBServer may be embedded to opt out of forward compatibility for this service. 611 | // Use of this interface is not recommended, as added methods to BTrDBServer will 612 | // result in compilation errors. 613 | type UnsafeBTrDBServer interface { 614 | mustEmbedUnimplementedBTrDBServer() 615 | } 616 | 617 | func RegisterBTrDBServer(s grpc.ServiceRegistrar, srv BTrDBServer) { 618 | s.RegisterService(&BTrDB_ServiceDesc, srv) 619 | } 620 | 621 | func _BTrDB_RawValues_Handler(srv interface{}, stream grpc.ServerStream) error { 622 | m := new(RawValuesParams) 623 | if err := stream.RecvMsg(m); err != nil { 624 | return err 625 | } 626 | return srv.(BTrDBServer).RawValues(m, &bTrDBRawValuesServer{stream}) 627 | } 628 | 629 | type BTrDB_RawValuesServer interface { 630 | Send(*RawValuesResponse) error 631 | grpc.ServerStream 632 | } 633 | 634 | type bTrDBRawValuesServer struct { 635 | grpc.ServerStream 636 | } 637 | 638 | func (x *bTrDBRawValuesServer) Send(m *RawValuesResponse) error { 639 | return x.ServerStream.SendMsg(m) 640 | } 641 | 642 | func _BTrDB_MultiRawValues_Handler(srv interface{}, stream grpc.ServerStream) error { 643 | m := new(MultiRawValuesParams) 644 | if err := stream.RecvMsg(m); err != nil { 645 | return err 646 | } 647 | return srv.(BTrDBServer).MultiRawValues(m, &bTrDBMultiRawValuesServer{stream}) 648 | } 649 | 650 | type BTrDB_MultiRawValuesServer interface { 651 | Send(*MultiRawValuesResponse) error 652 | grpc.ServerStream 653 | } 654 | 655 | type bTrDBMultiRawValuesServer struct { 656 | grpc.ServerStream 657 | } 658 | 659 | func (x *bTrDBMultiRawValuesServer) Send(m *MultiRawValuesResponse) error { 660 | return x.ServerStream.SendMsg(m) 661 | } 662 | 663 | func _BTrDB_AlignedWindows_Handler(srv interface{}, stream grpc.ServerStream) error { 664 | m := new(AlignedWindowsParams) 665 | if err := stream.RecvMsg(m); err != nil { 666 | return err 667 | } 668 | return srv.(BTrDBServer).AlignedWindows(m, &bTrDBAlignedWindowsServer{stream}) 669 | } 670 | 671 | type BTrDB_AlignedWindowsServer interface { 672 | Send(*AlignedWindowsResponse) error 673 | grpc.ServerStream 674 | } 675 | 676 | type bTrDBAlignedWindowsServer struct { 677 | grpc.ServerStream 678 | } 679 | 680 | func (x *bTrDBAlignedWindowsServer) Send(m *AlignedWindowsResponse) error { 681 | return x.ServerStream.SendMsg(m) 682 | } 683 | 684 | func _BTrDB_Windows_Handler(srv interface{}, stream grpc.ServerStream) error { 685 | m := new(WindowsParams) 686 | if err := stream.RecvMsg(m); err != nil { 687 | return err 688 | } 689 | return srv.(BTrDBServer).Windows(m, &bTrDBWindowsServer{stream}) 690 | } 691 | 692 | type BTrDB_WindowsServer interface { 693 | Send(*WindowsResponse) error 694 | grpc.ServerStream 695 | } 696 | 697 | type bTrDBWindowsServer struct { 698 | grpc.ServerStream 699 | } 700 | 701 | func (x *bTrDBWindowsServer) Send(m *WindowsResponse) error { 702 | return x.ServerStream.SendMsg(m) 703 | } 704 | 705 | func _BTrDB_StreamInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 706 | in := new(StreamInfoParams) 707 | if err := dec(in); err != nil { 708 | return nil, err 709 | } 710 | if interceptor == nil { 711 | return srv.(BTrDBServer).StreamInfo(ctx, in) 712 | } 713 | info := &grpc.UnaryServerInfo{ 714 | Server: srv, 715 | FullMethod: "/v5api.BTrDB/StreamInfo", 716 | } 717 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 718 | return srv.(BTrDBServer).StreamInfo(ctx, req.(*StreamInfoParams)) 719 | } 720 | return interceptor(ctx, in, info, handler) 721 | } 722 | 723 | func _BTrDB_SetStreamAnnotations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 724 | in := new(SetStreamAnnotationsParams) 725 | if err := dec(in); err != nil { 726 | return nil, err 727 | } 728 | if interceptor == nil { 729 | return srv.(BTrDBServer).SetStreamAnnotations(ctx, in) 730 | } 731 | info := &grpc.UnaryServerInfo{ 732 | Server: srv, 733 | FullMethod: "/v5api.BTrDB/SetStreamAnnotations", 734 | } 735 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 736 | return srv.(BTrDBServer).SetStreamAnnotations(ctx, req.(*SetStreamAnnotationsParams)) 737 | } 738 | return interceptor(ctx, in, info, handler) 739 | } 740 | 741 | func _BTrDB_SetStreamTags_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 742 | in := new(SetStreamTagsParams) 743 | if err := dec(in); err != nil { 744 | return nil, err 745 | } 746 | if interceptor == nil { 747 | return srv.(BTrDBServer).SetStreamTags(ctx, in) 748 | } 749 | info := &grpc.UnaryServerInfo{ 750 | Server: srv, 751 | FullMethod: "/v5api.BTrDB/SetStreamTags", 752 | } 753 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 754 | return srv.(BTrDBServer).SetStreamTags(ctx, req.(*SetStreamTagsParams)) 755 | } 756 | return interceptor(ctx, in, info, handler) 757 | } 758 | 759 | func _BTrDB_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 760 | in := new(CreateParams) 761 | if err := dec(in); err != nil { 762 | return nil, err 763 | } 764 | if interceptor == nil { 765 | return srv.(BTrDBServer).Create(ctx, in) 766 | } 767 | info := &grpc.UnaryServerInfo{ 768 | Server: srv, 769 | FullMethod: "/v5api.BTrDB/Create", 770 | } 771 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 772 | return srv.(BTrDBServer).Create(ctx, req.(*CreateParams)) 773 | } 774 | return interceptor(ctx, in, info, handler) 775 | } 776 | 777 | func _BTrDB_ListCollections_Handler(srv interface{}, stream grpc.ServerStream) error { 778 | m := new(ListCollectionsParams) 779 | if err := stream.RecvMsg(m); err != nil { 780 | return err 781 | } 782 | return srv.(BTrDBServer).ListCollections(m, &bTrDBListCollectionsServer{stream}) 783 | } 784 | 785 | type BTrDB_ListCollectionsServer interface { 786 | Send(*ListCollectionsResponse) error 787 | grpc.ServerStream 788 | } 789 | 790 | type bTrDBListCollectionsServer struct { 791 | grpc.ServerStream 792 | } 793 | 794 | func (x *bTrDBListCollectionsServer) Send(m *ListCollectionsResponse) error { 795 | return x.ServerStream.SendMsg(m) 796 | } 797 | 798 | func _BTrDB_LookupStreams_Handler(srv interface{}, stream grpc.ServerStream) error { 799 | m := new(LookupStreamsParams) 800 | if err := stream.RecvMsg(m); err != nil { 801 | return err 802 | } 803 | return srv.(BTrDBServer).LookupStreams(m, &bTrDBLookupStreamsServer{stream}) 804 | } 805 | 806 | type BTrDB_LookupStreamsServer interface { 807 | Send(*LookupStreamsResponse) error 808 | grpc.ServerStream 809 | } 810 | 811 | type bTrDBLookupStreamsServer struct { 812 | grpc.ServerStream 813 | } 814 | 815 | func (x *bTrDBLookupStreamsServer) Send(m *LookupStreamsResponse) error { 816 | return x.ServerStream.SendMsg(m) 817 | } 818 | 819 | func _BTrDB_Nearest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 820 | in := new(NearestParams) 821 | if err := dec(in); err != nil { 822 | return nil, err 823 | } 824 | if interceptor == nil { 825 | return srv.(BTrDBServer).Nearest(ctx, in) 826 | } 827 | info := &grpc.UnaryServerInfo{ 828 | Server: srv, 829 | FullMethod: "/v5api.BTrDB/Nearest", 830 | } 831 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 832 | return srv.(BTrDBServer).Nearest(ctx, req.(*NearestParams)) 833 | } 834 | return interceptor(ctx, in, info, handler) 835 | } 836 | 837 | func _BTrDB_Changes_Handler(srv interface{}, stream grpc.ServerStream) error { 838 | m := new(ChangesParams) 839 | if err := stream.RecvMsg(m); err != nil { 840 | return err 841 | } 842 | return srv.(BTrDBServer).Changes(m, &bTrDBChangesServer{stream}) 843 | } 844 | 845 | type BTrDB_ChangesServer interface { 846 | Send(*ChangesResponse) error 847 | grpc.ServerStream 848 | } 849 | 850 | type bTrDBChangesServer struct { 851 | grpc.ServerStream 852 | } 853 | 854 | func (x *bTrDBChangesServer) Send(m *ChangesResponse) error { 855 | return x.ServerStream.SendMsg(m) 856 | } 857 | 858 | func _BTrDB_Insert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 859 | in := new(InsertParams) 860 | if err := dec(in); err != nil { 861 | return nil, err 862 | } 863 | if interceptor == nil { 864 | return srv.(BTrDBServer).Insert(ctx, in) 865 | } 866 | info := &grpc.UnaryServerInfo{ 867 | Server: srv, 868 | FullMethod: "/v5api.BTrDB/Insert", 869 | } 870 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 871 | return srv.(BTrDBServer).Insert(ctx, req.(*InsertParams)) 872 | } 873 | return interceptor(ctx, in, info, handler) 874 | } 875 | 876 | func _BTrDB_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 877 | in := new(DeleteParams) 878 | if err := dec(in); err != nil { 879 | return nil, err 880 | } 881 | if interceptor == nil { 882 | return srv.(BTrDBServer).Delete(ctx, in) 883 | } 884 | info := &grpc.UnaryServerInfo{ 885 | Server: srv, 886 | FullMethod: "/v5api.BTrDB/Delete", 887 | } 888 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 889 | return srv.(BTrDBServer).Delete(ctx, req.(*DeleteParams)) 890 | } 891 | return interceptor(ctx, in, info, handler) 892 | } 893 | 894 | func _BTrDB_Info_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 895 | in := new(InfoParams) 896 | if err := dec(in); err != nil { 897 | return nil, err 898 | } 899 | if interceptor == nil { 900 | return srv.(BTrDBServer).Info(ctx, in) 901 | } 902 | info := &grpc.UnaryServerInfo{ 903 | Server: srv, 904 | FullMethod: "/v5api.BTrDB/Info", 905 | } 906 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 907 | return srv.(BTrDBServer).Info(ctx, req.(*InfoParams)) 908 | } 909 | return interceptor(ctx, in, info, handler) 910 | } 911 | 912 | func _BTrDB_FaultInject_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 913 | in := new(FaultInjectParams) 914 | if err := dec(in); err != nil { 915 | return nil, err 916 | } 917 | if interceptor == nil { 918 | return srv.(BTrDBServer).FaultInject(ctx, in) 919 | } 920 | info := &grpc.UnaryServerInfo{ 921 | Server: srv, 922 | FullMethod: "/v5api.BTrDB/FaultInject", 923 | } 924 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 925 | return srv.(BTrDBServer).FaultInject(ctx, req.(*FaultInjectParams)) 926 | } 927 | return interceptor(ctx, in, info, handler) 928 | } 929 | 930 | func _BTrDB_Flush_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 931 | in := new(FlushParams) 932 | if err := dec(in); err != nil { 933 | return nil, err 934 | } 935 | if interceptor == nil { 936 | return srv.(BTrDBServer).Flush(ctx, in) 937 | } 938 | info := &grpc.UnaryServerInfo{ 939 | Server: srv, 940 | FullMethod: "/v5api.BTrDB/Flush", 941 | } 942 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 943 | return srv.(BTrDBServer).Flush(ctx, req.(*FlushParams)) 944 | } 945 | return interceptor(ctx, in, info, handler) 946 | } 947 | 948 | func _BTrDB_Obliterate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 949 | in := new(ObliterateParams) 950 | if err := dec(in); err != nil { 951 | return nil, err 952 | } 953 | if interceptor == nil { 954 | return srv.(BTrDBServer).Obliterate(ctx, in) 955 | } 956 | info := &grpc.UnaryServerInfo{ 957 | Server: srv, 958 | FullMethod: "/v5api.BTrDB/Obliterate", 959 | } 960 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 961 | return srv.(BTrDBServer).Obliterate(ctx, req.(*ObliterateParams)) 962 | } 963 | return interceptor(ctx, in, info, handler) 964 | } 965 | 966 | func _BTrDB_GetMetadataUsage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 967 | in := new(MetadataUsageParams) 968 | if err := dec(in); err != nil { 969 | return nil, err 970 | } 971 | if interceptor == nil { 972 | return srv.(BTrDBServer).GetMetadataUsage(ctx, in) 973 | } 974 | info := &grpc.UnaryServerInfo{ 975 | Server: srv, 976 | FullMethod: "/v5api.BTrDB/GetMetadataUsage", 977 | } 978 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 979 | return srv.(BTrDBServer).GetMetadataUsage(ctx, req.(*MetadataUsageParams)) 980 | } 981 | return interceptor(ctx, in, info, handler) 982 | } 983 | 984 | func _BTrDB_GenerateCSV_Handler(srv interface{}, stream grpc.ServerStream) error { 985 | m := new(GenerateCSVParams) 986 | if err := stream.RecvMsg(m); err != nil { 987 | return err 988 | } 989 | return srv.(BTrDBServer).GenerateCSV(m, &bTrDBGenerateCSVServer{stream}) 990 | } 991 | 992 | type BTrDB_GenerateCSVServer interface { 993 | Send(*GenerateCSVResponse) error 994 | grpc.ServerStream 995 | } 996 | 997 | type bTrDBGenerateCSVServer struct { 998 | grpc.ServerStream 999 | } 1000 | 1001 | func (x *bTrDBGenerateCSVServer) Send(m *GenerateCSVResponse) error { 1002 | return x.ServerStream.SendMsg(m) 1003 | } 1004 | 1005 | func _BTrDB_SQLQuery_Handler(srv interface{}, stream grpc.ServerStream) error { 1006 | m := new(SQLQueryParams) 1007 | if err := stream.RecvMsg(m); err != nil { 1008 | return err 1009 | } 1010 | return srv.(BTrDBServer).SQLQuery(m, &bTrDBSQLQueryServer{stream}) 1011 | } 1012 | 1013 | type BTrDB_SQLQueryServer interface { 1014 | Send(*SQLQueryResponse) error 1015 | grpc.ServerStream 1016 | } 1017 | 1018 | type bTrDBSQLQueryServer struct { 1019 | grpc.ServerStream 1020 | } 1021 | 1022 | func (x *bTrDBSQLQueryServer) Send(m *SQLQueryResponse) error { 1023 | return x.ServerStream.SendMsg(m) 1024 | } 1025 | 1026 | func _BTrDB_Subscribe_Handler(srv interface{}, stream grpc.ServerStream) error { 1027 | m := new(SubscriptionParams) 1028 | if err := stream.RecvMsg(m); err != nil { 1029 | return err 1030 | } 1031 | return srv.(BTrDBServer).Subscribe(m, &bTrDBSubscribeServer{stream}) 1032 | } 1033 | 1034 | type BTrDB_SubscribeServer interface { 1035 | Send(*SubscriptionResp) error 1036 | grpc.ServerStream 1037 | } 1038 | 1039 | type bTrDBSubscribeServer struct { 1040 | grpc.ServerStream 1041 | } 1042 | 1043 | func (x *bTrDBSubscribeServer) Send(m *SubscriptionResp) error { 1044 | return x.ServerStream.SendMsg(m) 1045 | } 1046 | 1047 | func _BTrDB_SetCompactionConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 1048 | in := new(SetCompactionConfigParams) 1049 | if err := dec(in); err != nil { 1050 | return nil, err 1051 | } 1052 | if interceptor == nil { 1053 | return srv.(BTrDBServer).SetCompactionConfig(ctx, in) 1054 | } 1055 | info := &grpc.UnaryServerInfo{ 1056 | Server: srv, 1057 | FullMethod: "/v5api.BTrDB/SetCompactionConfig", 1058 | } 1059 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 1060 | return srv.(BTrDBServer).SetCompactionConfig(ctx, req.(*SetCompactionConfigParams)) 1061 | } 1062 | return interceptor(ctx, in, info, handler) 1063 | } 1064 | 1065 | func _BTrDB_GetCompactionConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 1066 | in := new(GetCompactionConfigParams) 1067 | if err := dec(in); err != nil { 1068 | return nil, err 1069 | } 1070 | if interceptor == nil { 1071 | return srv.(BTrDBServer).GetCompactionConfig(ctx, in) 1072 | } 1073 | info := &grpc.UnaryServerInfo{ 1074 | Server: srv, 1075 | FullMethod: "/v5api.BTrDB/GetCompactionConfig", 1076 | } 1077 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 1078 | return srv.(BTrDBServer).GetCompactionConfig(ctx, req.(*GetCompactionConfigParams)) 1079 | } 1080 | return interceptor(ctx, in, info, handler) 1081 | } 1082 | 1083 | // BTrDB_ServiceDesc is the grpc.ServiceDesc for BTrDB service. 1084 | // It's only intended for direct use with grpc.RegisterService, 1085 | // and not to be introspected or modified (even as a copy) 1086 | var BTrDB_ServiceDesc = grpc.ServiceDesc{ 1087 | ServiceName: "v5api.BTrDB", 1088 | HandlerType: (*BTrDBServer)(nil), 1089 | Methods: []grpc.MethodDesc{ 1090 | { 1091 | MethodName: "StreamInfo", 1092 | Handler: _BTrDB_StreamInfo_Handler, 1093 | }, 1094 | { 1095 | MethodName: "SetStreamAnnotations", 1096 | Handler: _BTrDB_SetStreamAnnotations_Handler, 1097 | }, 1098 | { 1099 | MethodName: "SetStreamTags", 1100 | Handler: _BTrDB_SetStreamTags_Handler, 1101 | }, 1102 | { 1103 | MethodName: "Create", 1104 | Handler: _BTrDB_Create_Handler, 1105 | }, 1106 | { 1107 | MethodName: "Nearest", 1108 | Handler: _BTrDB_Nearest_Handler, 1109 | }, 1110 | { 1111 | MethodName: "Insert", 1112 | Handler: _BTrDB_Insert_Handler, 1113 | }, 1114 | { 1115 | MethodName: "Delete", 1116 | Handler: _BTrDB_Delete_Handler, 1117 | }, 1118 | { 1119 | MethodName: "Info", 1120 | Handler: _BTrDB_Info_Handler, 1121 | }, 1122 | { 1123 | MethodName: "FaultInject", 1124 | Handler: _BTrDB_FaultInject_Handler, 1125 | }, 1126 | { 1127 | MethodName: "Flush", 1128 | Handler: _BTrDB_Flush_Handler, 1129 | }, 1130 | { 1131 | MethodName: "Obliterate", 1132 | Handler: _BTrDB_Obliterate_Handler, 1133 | }, 1134 | { 1135 | MethodName: "GetMetadataUsage", 1136 | Handler: _BTrDB_GetMetadataUsage_Handler, 1137 | }, 1138 | { 1139 | MethodName: "SetCompactionConfig", 1140 | Handler: _BTrDB_SetCompactionConfig_Handler, 1141 | }, 1142 | { 1143 | MethodName: "GetCompactionConfig", 1144 | Handler: _BTrDB_GetCompactionConfig_Handler, 1145 | }, 1146 | }, 1147 | Streams: []grpc.StreamDesc{ 1148 | { 1149 | StreamName: "RawValues", 1150 | Handler: _BTrDB_RawValues_Handler, 1151 | ServerStreams: true, 1152 | }, 1153 | { 1154 | StreamName: "MultiRawValues", 1155 | Handler: _BTrDB_MultiRawValues_Handler, 1156 | ServerStreams: true, 1157 | }, 1158 | { 1159 | StreamName: "AlignedWindows", 1160 | Handler: _BTrDB_AlignedWindows_Handler, 1161 | ServerStreams: true, 1162 | }, 1163 | { 1164 | StreamName: "Windows", 1165 | Handler: _BTrDB_Windows_Handler, 1166 | ServerStreams: true, 1167 | }, 1168 | { 1169 | StreamName: "ListCollections", 1170 | Handler: _BTrDB_ListCollections_Handler, 1171 | ServerStreams: true, 1172 | }, 1173 | { 1174 | StreamName: "LookupStreams", 1175 | Handler: _BTrDB_LookupStreams_Handler, 1176 | ServerStreams: true, 1177 | }, 1178 | { 1179 | StreamName: "Changes", 1180 | Handler: _BTrDB_Changes_Handler, 1181 | ServerStreams: true, 1182 | }, 1183 | { 1184 | StreamName: "GenerateCSV", 1185 | Handler: _BTrDB_GenerateCSV_Handler, 1186 | ServerStreams: true, 1187 | }, 1188 | { 1189 | StreamName: "SQLQuery", 1190 | Handler: _BTrDB_SQLQuery_Handler, 1191 | ServerStreams: true, 1192 | }, 1193 | { 1194 | StreamName: "Subscribe", 1195 | Handler: _BTrDB_Subscribe_Handler, 1196 | ServerStreams: true, 1197 | }, 1198 | }, 1199 | Metadata: "btrdb.proto", 1200 | } 1201 | -------------------------------------------------------------------------------- /v5api/gen.go: -------------------------------------------------------------------------------- 1 | package v5api 2 | 3 | //go:generate protoc -I /usr/local/include -I ./include -I . --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative btrdb.proto 4 | //go:generate protoc -I /usr/local/include -I ./include -I . --grpc-gateway_out=logtostderr=true:. --grpc-gateway_opt=paths=source_relative btrdb.proto 5 | // //go:generate protoc -I/usr/local/include -I ./include -I. --openapiv2_out=logtostderr=true:. btrdb.proto 6 | -------------------------------------------------------------------------------- /v5api/include/google/api/annotations.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/http.proto"; 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "AnnotationsProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | extend google.protobuf.MethodOptions { 29 | // See `HttpRule`. 30 | HttpRule http = 72295728; 31 | } 32 | -------------------------------------------------------------------------------- /v5api/include/google/api/http.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option cc_enable_arenas = true; 20 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 21 | option java_multiple_files = true; 22 | option java_outer_classname = "HttpProto"; 23 | option java_package = "com.google.api"; 24 | option objc_class_prefix = "GAPI"; 25 | 26 | // Defines the HTTP configuration for an API service. It contains a list of 27 | // [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method 28 | // to one or more HTTP REST API methods. 29 | message Http { 30 | // A list of HTTP configuration rules that apply to individual API methods. 31 | // 32 | // **NOTE:** All service configuration rules follow "last one wins" order. 33 | repeated HttpRule rules = 1; 34 | 35 | // When set to true, URL path parameters will be fully URI-decoded except in 36 | // cases of single segment matches in reserved expansion, where "%2F" will be 37 | // left encoded. 38 | // 39 | // The default behavior is to not decode RFC 6570 reserved characters in multi 40 | // segment matches. 41 | bool fully_decode_reserved_expansion = 2; 42 | } 43 | 44 | // # gRPC Transcoding 45 | // 46 | // gRPC Transcoding is a feature for mapping between a gRPC method and one or 47 | // more HTTP REST endpoints. It allows developers to build a single API service 48 | // that supports both gRPC APIs and REST APIs. Many systems, including [Google 49 | // APIs](https://github.com/googleapis/googleapis), 50 | // [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC 51 | // Gateway](https://github.com/grpc-ecosystem/grpc-gateway), 52 | // and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature 53 | // and use it for large scale production services. 54 | // 55 | // `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies 56 | // how different portions of the gRPC request message are mapped to the URL 57 | // path, URL query parameters, and HTTP request body. It also controls how the 58 | // gRPC response message is mapped to the HTTP response body. `HttpRule` is 59 | // typically specified as an `google.api.http` annotation on the gRPC method. 60 | // 61 | // Each mapping specifies a URL path template and an HTTP method. The path 62 | // template may refer to one or more fields in the gRPC request message, as long 63 | // as each field is a non-repeated field with a primitive (non-message) type. 64 | // The path template controls how fields of the request message are mapped to 65 | // the URL path. 66 | // 67 | // Example: 68 | // 69 | // service Messaging { 70 | // rpc GetMessage(GetMessageRequest) returns (Message) { 71 | // option (google.api.http) = { 72 | // get: "/v1/{name=messages/*}" 73 | // }; 74 | // } 75 | // } 76 | // message GetMessageRequest { 77 | // string name = 1; // Mapped to URL path. 78 | // } 79 | // message Message { 80 | // string text = 1; // The resource content. 81 | // } 82 | // 83 | // This enables an HTTP REST to gRPC mapping as below: 84 | // 85 | // HTTP | gRPC 86 | // -----|----- 87 | // `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` 88 | // 89 | // Any fields in the request message which are not bound by the path template 90 | // automatically become HTTP query parameters if there is no HTTP request body. 91 | // For example: 92 | // 93 | // service Messaging { 94 | // rpc GetMessage(GetMessageRequest) returns (Message) { 95 | // option (google.api.http) = { 96 | // get:"/v1/messages/{message_id}" 97 | // }; 98 | // } 99 | // } 100 | // message GetMessageRequest { 101 | // message SubMessage { 102 | // string subfield = 1; 103 | // } 104 | // string message_id = 1; // Mapped to URL path. 105 | // int64 revision = 2; // Mapped to URL query parameter `revision`. 106 | // SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. 107 | // } 108 | // 109 | // This enables a HTTP JSON to RPC mapping as below: 110 | // 111 | // HTTP | gRPC 112 | // -----|----- 113 | // `GET /v1/messages/123456?revision=2&sub.subfield=foo` | 114 | // `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: 115 | // "foo"))` 116 | // 117 | // Note that fields which are mapped to URL query parameters must have a 118 | // primitive type or a repeated primitive type or a non-repeated message type. 119 | // In the case of a repeated type, the parameter can be repeated in the URL 120 | // as `...?param=A¶m=B`. In the case of a message type, each field of the 121 | // message is mapped to a separate parameter, such as 122 | // `...?foo.a=A&foo.b=B&foo.c=C`. 123 | // 124 | // For HTTP methods that allow a request body, the `body` field 125 | // specifies the mapping. Consider a REST update method on the 126 | // message resource collection: 127 | // 128 | // service Messaging { 129 | // rpc UpdateMessage(UpdateMessageRequest) returns (Message) { 130 | // option (google.api.http) = { 131 | // patch: "/v1/messages/{message_id}" 132 | // body: "message" 133 | // }; 134 | // } 135 | // } 136 | // message UpdateMessageRequest { 137 | // string message_id = 1; // mapped to the URL 138 | // Message message = 2; // mapped to the body 139 | // } 140 | // 141 | // The following HTTP JSON to RPC mapping is enabled, where the 142 | // representation of the JSON in the request body is determined by 143 | // protos JSON encoding: 144 | // 145 | // HTTP | gRPC 146 | // -----|----- 147 | // `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: 148 | // "123456" message { text: "Hi!" })` 149 | // 150 | // The special name `*` can be used in the body mapping to define that 151 | // every field not bound by the path template should be mapped to the 152 | // request body. This enables the following alternative definition of 153 | // the update method: 154 | // 155 | // service Messaging { 156 | // rpc UpdateMessage(Message) returns (Message) { 157 | // option (google.api.http) = { 158 | // patch: "/v1/messages/{message_id}" 159 | // body: "*" 160 | // }; 161 | // } 162 | // } 163 | // message Message { 164 | // string message_id = 1; 165 | // string text = 2; 166 | // } 167 | // 168 | // 169 | // The following HTTP JSON to RPC mapping is enabled: 170 | // 171 | // HTTP | gRPC 172 | // -----|----- 173 | // `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: 174 | // "123456" text: "Hi!")` 175 | // 176 | // Note that when using `*` in the body mapping, it is not possible to 177 | // have HTTP parameters, as all fields not bound by the path end in 178 | // the body. This makes this option more rarely used in practice when 179 | // defining REST APIs. The common usage of `*` is in custom methods 180 | // which don't use the URL at all for transferring data. 181 | // 182 | // It is possible to define multiple HTTP methods for one RPC by using 183 | // the `additional_bindings` option. Example: 184 | // 185 | // service Messaging { 186 | // rpc GetMessage(GetMessageRequest) returns (Message) { 187 | // option (google.api.http) = { 188 | // get: "/v1/messages/{message_id}" 189 | // additional_bindings { 190 | // get: "/v1/users/{user_id}/messages/{message_id}" 191 | // } 192 | // }; 193 | // } 194 | // } 195 | // message GetMessageRequest { 196 | // string message_id = 1; 197 | // string user_id = 2; 198 | // } 199 | // 200 | // This enables the following two alternative HTTP JSON to RPC mappings: 201 | // 202 | // HTTP | gRPC 203 | // -----|----- 204 | // `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` 205 | // `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: 206 | // "123456")` 207 | // 208 | // ## Rules for HTTP mapping 209 | // 210 | // 1. Leaf request fields (recursive expansion nested messages in the request 211 | // message) are classified into three categories: 212 | // - Fields referred by the path template. They are passed via the URL path. 213 | // - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP 214 | // request body. 215 | // - All other fields are passed via the URL query parameters, and the 216 | // parameter name is the field path in the request message. A repeated 217 | // field can be represented as multiple query parameters under the same 218 | // name. 219 | // 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query parameter, all fields 220 | // are passed via URL path and HTTP request body. 221 | // 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP request body, all 222 | // fields are passed via URL path and URL query parameters. 223 | // 224 | // ### Path template syntax 225 | // 226 | // Template = "/" Segments [ Verb ] ; 227 | // Segments = Segment { "/" Segment } ; 228 | // Segment = "*" | "**" | LITERAL | Variable ; 229 | // Variable = "{" FieldPath [ "=" Segments ] "}" ; 230 | // FieldPath = IDENT { "." IDENT } ; 231 | // Verb = ":" LITERAL ; 232 | // 233 | // The syntax `*` matches a single URL path segment. The syntax `**` matches 234 | // zero or more URL path segments, which must be the last part of the URL path 235 | // except the `Verb`. 236 | // 237 | // The syntax `Variable` matches part of the URL path as specified by its 238 | // template. A variable template must not contain other variables. If a variable 239 | // matches a single path segment, its template may be omitted, e.g. `{var}` 240 | // is equivalent to `{var=*}`. 241 | // 242 | // The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` 243 | // contains any reserved character, such characters should be percent-encoded 244 | // before the matching. 245 | // 246 | // If a variable contains exactly one path segment, such as `"{var}"` or 247 | // `"{var=*}"`, when such a variable is expanded into a URL path on the client 248 | // side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The 249 | // server side does the reverse decoding. Such variables show up in the 250 | // [Discovery 251 | // Document](https://developers.google.com/discovery/v1/reference/apis) as 252 | // `{var}`. 253 | // 254 | // If a variable contains multiple path segments, such as `"{var=foo/*}"` 255 | // or `"{var=**}"`, when such a variable is expanded into a URL path on the 256 | // client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. 257 | // The server side does the reverse decoding, except "%2F" and "%2f" are left 258 | // unchanged. Such variables show up in the 259 | // [Discovery 260 | // Document](https://developers.google.com/discovery/v1/reference/apis) as 261 | // `{+var}`. 262 | // 263 | // ## Using gRPC API Service Configuration 264 | // 265 | // gRPC API Service Configuration (service config) is a configuration language 266 | // for configuring a gRPC service to become a user-facing product. The 267 | // service config is simply the YAML representation of the `google.api.Service` 268 | // proto message. 269 | // 270 | // As an alternative to annotating your proto file, you can configure gRPC 271 | // transcoding in your service config YAML files. You do this by specifying a 272 | // `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same 273 | // effect as the proto annotation. This can be particularly useful if you 274 | // have a proto that is reused in multiple services. Note that any transcoding 275 | // specified in the service config will override any matching transcoding 276 | // configuration in the proto. 277 | // 278 | // Example: 279 | // 280 | // http: 281 | // rules: 282 | // # Selects a gRPC method and applies HttpRule to it. 283 | // - selector: example.v1.Messaging.GetMessage 284 | // get: /v1/messages/{message_id}/{sub.subfield} 285 | // 286 | // ## Special notes 287 | // 288 | // When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the 289 | // proto to JSON conversion must follow the [proto3 290 | // specification](https://developers.google.com/protocol-buffers/docs/proto3#json). 291 | // 292 | // While the single segment variable follows the semantics of 293 | // [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String 294 | // Expansion, the multi segment variable **does not** follow RFC 6570 Section 295 | // 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion 296 | // does not expand special characters like `?` and `#`, which would lead 297 | // to invalid URLs. As the result, gRPC Transcoding uses a custom encoding 298 | // for multi segment variables. 299 | // 300 | // The path variables **must not** refer to any repeated or mapped field, 301 | // because client libraries are not capable of handling such variable expansion. 302 | // 303 | // The path variables **must not** capture the leading "/" character. The reason 304 | // is that the most common use case "{var}" does not capture the leading "/" 305 | // character. For consistency, all path variables must share the same behavior. 306 | // 307 | // Repeated message fields must not be mapped to URL query parameters, because 308 | // no client library can support such complicated mapping. 309 | // 310 | // If an API needs to use a JSON array for request or response body, it can map 311 | // the request or response body to a repeated field. However, some gRPC 312 | // Transcoding implementations may not support this feature. 313 | message HttpRule { 314 | // Selects a method to which this rule applies. 315 | // 316 | // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. 317 | string selector = 1; 318 | 319 | // Determines the URL pattern is matched by this rules. This pattern can be 320 | // used with any of the {get|put|post|delete|patch} methods. A custom method 321 | // can be defined using the 'custom' field. 322 | oneof pattern { 323 | // Maps to HTTP GET. Used for listing and getting information about 324 | // resources. 325 | string get = 2; 326 | 327 | // Maps to HTTP PUT. Used for replacing a resource. 328 | string put = 3; 329 | 330 | // Maps to HTTP POST. Used for creating a resource or performing an action. 331 | string post = 4; 332 | 333 | // Maps to HTTP DELETE. Used for deleting a resource. 334 | string delete = 5; 335 | 336 | // Maps to HTTP PATCH. Used for updating a resource. 337 | string patch = 6; 338 | 339 | // The custom pattern is used for specifying an HTTP method that is not 340 | // included in the `pattern` field, such as HEAD, or "*" to leave the 341 | // HTTP method unspecified for this rule. The wild-card rule is useful 342 | // for services that provide content to Web (HTML) clients. 343 | CustomHttpPattern custom = 8; 344 | } 345 | 346 | // The name of the request field whose value is mapped to the HTTP request 347 | // body, or `*` for mapping all request fields not captured by the path 348 | // pattern to the HTTP body, or omitted for not having any HTTP request body. 349 | // 350 | // NOTE: the referred field must be present at the top-level of the request 351 | // message type. 352 | string body = 7; 353 | 354 | // Optional. The name of the response field whose value is mapped to the HTTP 355 | // response body. When omitted, the entire response message will be used 356 | // as the HTTP response body. 357 | // 358 | // NOTE: The referred field must be present at the top-level of the response 359 | // message type. 360 | string response_body = 12; 361 | 362 | // Additional HTTP bindings for the selector. Nested bindings must 363 | // not contain an `additional_bindings` field themselves (that is, 364 | // the nesting may only be one level deep). 365 | repeated HttpRule additional_bindings = 11; 366 | } 367 | 368 | // A custom pattern is used for defining custom HTTP verb. 369 | message CustomHttpPattern { 370 | // The name of this custom HTTP verb. 371 | string kind = 1; 372 | 373 | // The path matched by this custom verb. 374 | string path = 2; 375 | } 376 | --------------------------------------------------------------------------------