YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/rocksdb/utilities/document_db.h
Line
Count
Source
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2
//  This source code is licensed under the BSD-style license found in the
3
//  LICENSE file in the root directory of this source tree. An additional grant
4
//  of patent rights can be found in the PATENTS file in the same directory.
5
//
6
// The following only applies to changes made to this file as part of YugaByte development.
7
//
8
// Portions Copyright (c) YugaByte, Inc.
9
//
10
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
11
// in compliance with the License.  You may obtain a copy of the License at
12
//
13
// http://www.apache.org/licenses/LICENSE-2.0
14
//
15
// Unless required by applicable law or agreed to in writing, software distributed under the License
16
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17
// or implied.  See the License for the specific language governing permissions and limitations
18
// under the License.
19
//
20
21
#pragma once
22
#ifndef ROCKSDB_LITE
23
24
#include <string>
25
#include <vector>
26
27
#include "yb/rocksdb/utilities/stackable_db.h"
28
#include "yb/rocksdb/utilities/json_document.h"
29
#include "yb/rocksdb/db.h"
30
31
namespace rocksdb {
32
33
// IMPORTANT: DocumentDB is a work in progress. It is unstable and we might
34
// change the API without warning. Talk to RocksDB team before using this in
35
// production ;)
36
37
// DocumentDB is a layer on top of RocksDB that provides a very simple JSON API.
38
// When creating a DB, you specify a list of indexes you want to keep on your
39
// data. You can insert a JSON document to the DB, which is automatically
40
// indexed. Every document added to the DB needs to have "_id" field which is
41
// automatically indexed and is an unique primary key. All other indexes are
42
// non-unique.
43
44
// NOTE: field names in the JSON are NOT allowed to start with '$' or
45
// contain '.'. We don't currently enforce that rule, but will start behaving
46
// badly.
47
48
// Cursor is what you get as a result of executing query. To get all
49
// results from a query, call Next() on a Cursor while  Valid() returns true
50
class Cursor {
51
 public:
52
28
  Cursor() = default;
53
28
  virtual ~Cursor() {}
54
55
  virtual bool Valid() const = 0;
56
  virtual void Next() = 0;
57
  // Lifecycle of the returned JSONDocument is until the next Next() call
58
  virtual const JSONDocument& document() const = 0;
59
  virtual Status status() const = 0;
60
61
 private:
62
  // No copying allowed
63
  Cursor(const Cursor&);
64
  void operator=(const Cursor&);
65
};
66
67
struct DocumentDBOptions {
68
  int background_threads = 4;
69
  uint64_t memtable_size = 128 * 1024 * 1024;    // 128 MB
70
  uint64_t cache_size = 1 * 1024 * 1024 * 1024;  // 1 GB
71
};
72
73
// TODO(icanadi) Add `JSONDocument* info` parameter to all calls that can be
74
// used by the caller to get more information about the call execution (number
75
// of dropped records, number of updated records, etc.)
76
class DocumentDB : public StackableDB {
77
 public:
78
  struct IndexDescriptor {
79
    // Currently, you can only define an index on a single field. To specify an
80
    // index on a field X, set index description to JSON "{X: 1}"
81
    // Currently the value needs to be 1, which means ascending.
82
    // In the future, we plan to also support indexes on multiple keys, where
83
    // you could mix ascending sorting (1) with descending sorting indexes (-1)
84
    JSONDocument* description;
85
    std::string name;
86
  };
87
88
  // Open DocumentDB with specified indexes. The list of indexes has to be
89
  // complete, i.e. include all indexes present in the DB, except the primary
90
  // key index.
91
  // Otherwise, Open() will return an error
92
  static Status Open(const DocumentDBOptions& options, const std::string& name,
93
                     const std::vector<IndexDescriptor>& indexes,
94
                     DocumentDB** db, bool read_only = false);
95
96
3
  explicit DocumentDB(DB* db) : StackableDB(db) {}
97
98
  // Create a new index. It will stop all writes for the duration of the call.
99
  // All current documents in the DB are scanned and corresponding index entries
100
  // are created
101
  virtual Status CreateIndex(const WriteOptions& write_options,
102
                             const IndexDescriptor& index) = 0;
103
104
  // Drop an index. Client is responsible to make sure that index is not being
105
  // used by currently executing queries
106
  virtual Status DropIndex(const std::string& name) = 0;
107
108
  // Insert a document to the DB. The document needs to have a primary key "_id"
109
  // which can either be a string or an integer. Otherwise the write will fail
110
  // with InvalidArgument.
111
  virtual Status Insert(const WriteOptions& options,
112
                        const JSONDocument& document) = 0;
113
114
  // Deletes all documents matching a filter atomically
115
  virtual Status Remove(const ReadOptions& read_options,
116
                        const WriteOptions& write_options,
117
                        const JSONDocument& query) = 0;
118
119
  // Does this sequence of operations:
120
  // 1. Find all documents matching a filter
121
  // 2. For all documents, atomically:
122
  // 2.1. apply the update operators
123
  // 2.2. update the secondary indexes
124
  //
125
  // Currently only $set update operator is supported.
126
  // Syntax is: {$set: {key1: value1, key2: value2, etc...}}
127
  // This operator will change a document's key1 field to value1, key2 to
128
  // value2, etc. New values will be set even if a document didn't have an entry
129
  // for the specified key.
130
  //
131
  // You can not change a primary key of a document.
132
  //
133
  // Update example: Update({id: {$gt: 5}, $index: id}, {$set: {enabled: true}})
134
  virtual Status Update(const ReadOptions& read_options,
135
                        const WriteOptions& write_options,
136
                        const JSONDocument& filter,
137
                        const JSONDocument& updates) = 0;
138
139
  // query has to be an array in which every element is an operator. Currently
140
  // only $filter operator is supported. Syntax of $filter operator is:
141
  // {$filter: {key1: condition1, key2: condition2, etc.}} where conditions can
142
  // be either:
143
  // 1) a single value in which case the condition is equality condition, or
144
  // 2) a defined operators, like {$gt: 4}, which will match all documents that
145
  // have key greater than 4.
146
  //
147
  // Supported operators are:
148
  // 1) $gt -- greater than
149
  // 2) $gte -- greater than or equal
150
  // 3) $lt -- less than
151
  // 4) $lte -- less than or equal
152
  // If you want the filter to use an index, you need to specify it like this:
153
  // {$filter: {...(conditions)..., $index: index_name}}
154
  //
155
  // Example query:
156
  // * [{$filter: {name: John, age: {$gte: 18}, $index: age}}]
157
  // will return all Johns whose age is greater or equal to 18 and it will use
158
  // index "age" to satisfy the query.
159
  virtual Cursor* Query(const ReadOptions& read_options,
160
                        const JSONDocument& query) = 0;
161
};
162
163
}  // namespace rocksdb
164
#endif  // ROCKSDB_LITE