statelydb 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +202 -0
- data/README.md +2 -9
- data/lib/api/db/continue_scan_pb.rb +17 -0
- data/lib/api/db/scan_pb.rb +19 -0
- data/lib/api/db/service_pb.rb +3 -1
- data/lib/api/db/service_services_pb.rb +18 -0
- data/lib/common/auth/auth_token_provider.rb +6 -7
- data/lib/common/auth/token_fetcher.rb +3 -3
- data/lib/common/net/conn.rb +5 -4
- data/lib/key_path.rb +1 -1
- data/lib/stately_codes.rb +12 -0
- data/lib/statelydb.rb +10 -6
- data/sig/statelydb.rbi +19 -11
- data/sig/statelydb.rbs +15 -7
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d483a4f27e6db0ab8cf105436628e289d4a052165f52255bc27d75f7e7f3a732
|
4
|
+
data.tar.gz: 594c97893a48d797d1bda478745aca8c3d4d7df75d14893c5c7dd806ae4916b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c8e520f46d720316d90c58f9737d16c5527631ebaebbbe1181bf2b9e75cd1f100fcfe69cf78c8df46c41298cb791f0ba60f1b58c425a49289c8453ca01f119d
|
7
|
+
data.tar.gz: 7b655f365beffac08bfe29ecff25962c80794becb1788509380d893f0fc29078c4c97f00d2cff8aed75a870d1167a7a36dd9ea8ec3c5ad166fa0387f85fb387f
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
|
2
|
+
Apache License
|
3
|
+
Version 2.0, January 2004
|
4
|
+
http://www.apache.org/licenses/
|
5
|
+
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
7
|
+
|
8
|
+
1. Definitions.
|
9
|
+
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
12
|
+
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
14
|
+
the copyright owner that is granting the License.
|
15
|
+
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
17
|
+
other entities that control, are controlled by, or are under common
|
18
|
+
control with that entity. For the purposes of this definition,
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
20
|
+
direction or management of such entity, whether by contract or
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
23
|
+
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
25
|
+
exercising permissions granted by this License.
|
26
|
+
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
28
|
+
including but not limited to software source code, documentation
|
29
|
+
source, and configuration files.
|
30
|
+
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
32
|
+
transformation or translation of a Source form, including but
|
33
|
+
not limited to compiled object code, generated documentation,
|
34
|
+
and conversions to other media types.
|
35
|
+
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
37
|
+
Object form, made available under the License, as indicated by a
|
38
|
+
copyright notice that is included in or attached to the work
|
39
|
+
(an example is provided in the Appendix below).
|
40
|
+
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
47
|
+
the Work and Derivative Works thereof.
|
48
|
+
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
50
|
+
the original version of the Work and any modifications or additions
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
62
|
+
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
65
|
+
subsequently incorporated within the Work.
|
66
|
+
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
73
|
+
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
79
|
+
where such license applies only to those patent claims licensable
|
80
|
+
by such Contributor that are necessarily infringed by their
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
83
|
+
institute patent litigation against any entity (including a
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
86
|
+
or contributory patent infringement, then any patent licenses
|
87
|
+
granted to You under this License for that Work shall terminate
|
88
|
+
as of the date such litigation is filed.
|
89
|
+
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
92
|
+
modifications, and in Source or Object form, provided that You
|
93
|
+
meet the following conditions:
|
94
|
+
|
95
|
+
(a) You must give any other recipients of the Work or
|
96
|
+
Derivative Works a copy of this License; and
|
97
|
+
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
99
|
+
stating that You changed the files; and
|
100
|
+
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
103
|
+
attribution notices from the Source form of the Work,
|
104
|
+
excluding those notices that do not pertain to any part of
|
105
|
+
the Derivative Works; and
|
106
|
+
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
109
|
+
include a readable copy of the attribution notices contained
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
112
|
+
of the following places: within a NOTICE text file distributed
|
113
|
+
as part of the Derivative Works; within the Source form or
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
115
|
+
within a display generated by the Derivative Works, if and
|
116
|
+
wherever such third-party notices normally appear. The contents
|
117
|
+
of the NOTICE file are for informational purposes only and
|
118
|
+
do not modify the License. You may add Your own attribution
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
121
|
+
that such additional attribution notices cannot be construed
|
122
|
+
as modifying the License.
|
123
|
+
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
125
|
+
may provide additional or different license terms and conditions
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
129
|
+
the conditions stated in this License.
|
130
|
+
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
134
|
+
this License, without any additional terms or conditions.
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
136
|
+
the terms of any separate license agreement you may have executed
|
137
|
+
with Licensor regarding such Contributions.
|
138
|
+
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
141
|
+
except as required for reasonable and customary use in describing the
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
143
|
+
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
153
|
+
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
159
|
+
incidental, or consequential damages of any character arising as a
|
160
|
+
result of this License or out of the use or inability to use the
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
163
|
+
other commercial damages or losses), even if such Contributor
|
164
|
+
has been advised of the possibility of such damages.
|
165
|
+
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
169
|
+
or other liability obligations and/or rights consistent with this
|
170
|
+
License. However, in accepting such obligations, You may act only
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
175
|
+
of your accepting any such warranty or additional liability.
|
176
|
+
|
177
|
+
END OF TERMS AND CONDITIONS
|
178
|
+
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
180
|
+
|
181
|
+
To apply the Apache License to your work, attach the following
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
183
|
+
replaced with your own identifying information. (Don't include
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
185
|
+
comment syntax for the file format. We also recommend that a
|
186
|
+
file or class name and description of purpose be included on the
|
187
|
+
same "printed page" as the copyright notice for easier
|
188
|
+
identification within third-party archives.
|
189
|
+
|
190
|
+
Copyright 2024 Stately Cloud, Inc.
|
191
|
+
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
193
|
+
you may not use this file except in compliance with the License.
|
194
|
+
You may obtain a copy of the License at
|
195
|
+
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
197
|
+
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
201
|
+
See the License for the specific language governing permissions and
|
202
|
+
limitations under the License.
|
data/README.md
CHANGED
@@ -8,13 +8,6 @@ This is the Ruby SDK for [StatelyDB](https://stately.cloud).
|
|
8
8
|
|
9
9
|
We're still in an invite-only preview mode - if you're interested, please reach out to [preview@stately.cloud](mailto:preview@stately.cloud?subject=Early%20Access%20Program).
|
10
10
|
|
11
|
-
When you join the preview program, we'll set you up with a few bits of information:
|
12
|
-
|
13
|
-
1. `STATELY_CLIENT_ID` - a client identifier so we know what client you are.
|
14
|
-
2. `STATELY_CLIENT_SECRET` - a sensitive secret that lets your applications authenticate with the API.
|
15
|
-
3. A store ID that identifies which store in your organization you're using.
|
16
|
-
4. Access to our in-depth [Getting Started Guide].
|
17
|
-
|
18
11
|
Begin by following our [Getting Started Guide] which will help you define, generate, and publish a DB schema so that it can be used.
|
19
12
|
|
20
13
|
##### Install the SDK
|
@@ -32,8 +25,8 @@ Create an authenticated client, then import your item types from your generated
|
|
32
25
|
require_relative 'schema/stately'
|
33
26
|
|
34
27
|
def put_my_item
|
35
|
-
# Create a client. This will use the environment
|
36
|
-
#
|
28
|
+
# Create a client. This will use the environment variable
|
29
|
+
# STATELY_ACCESS_KEY to read your access key
|
37
30
|
client = StatelyDB::Client.new(store_id: <my-store-id>)
|
38
31
|
|
39
32
|
# Instantiate an item from your schema
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/continue_scan.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
|
8
|
+
descriptor_data = "\n\x16\x64\x62/continue_scan.proto\x12\nstately.db\"`\n\x13\x43ontinueScanRequest\x12\x1d\n\ntoken_data\x18\x01 \x01(\x0cR\ttokenData\x12*\n\x11schema_version_id\x18\x02 \x01(\rR\x0fschemaVersionIdBl\n\x0e\x63om.stately.dbB\x11\x43ontinueScanProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
|
13
|
+
module Stately
|
14
|
+
module Db
|
15
|
+
ContinueScanRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ContinueScanRequest").msgclass
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/scan.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
|
8
|
+
descriptor_data = "\n\rdb/scan.proto\x12\nstately.db\"9\n\x0f\x46ilterCondition\x12\x1d\n\titem_type\x18\x01 \x01(\tH\x00R\x08itemTypeB\x07\n\x05value\"\x88\x02\n\x10\x42\x65ginScanRequest\x12\x19\n\x08store_id\x18\x01 \x01(\x04R\x07storeId\x12\x46\n\x10\x66ilter_condition\x18\x02 \x03(\x0b\x32\x1b.stately.db.FilterConditionR\x0f\x66ilterCondition\x12\x14\n\x05limit\x18\x03 \x01(\rR\x05limit\x12O\n\x13segmentation_params\x18\x04 \x01(\x0b\x32\x1e.stately.db.SegmentationParamsR\x12segmentationParams\x12*\n\x11schema_version_id\x18\x05 \x01(\rR\x0fschemaVersionId\"`\n\x12SegmentationParams\x12%\n\x0etotal_segments\x18\x05 \x01(\rR\rtotalSegments\x12#\n\rsegment_index\x18\x06 \x01(\rR\x0csegmentIndexBd\n\x0e\x63om.stately.dbB\tScanProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
|
13
|
+
module Stately
|
14
|
+
module Db
|
15
|
+
FilterCondition = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.FilterCondition").msgclass
|
16
|
+
BeginScanRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.BeginScanRequest").msgclass
|
17
|
+
SegmentationParams = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.SegmentationParams").msgclass
|
18
|
+
end
|
19
|
+
end
|
data/lib/api/db/service_pb.rb
CHANGED
@@ -5,16 +5,18 @@
|
|
5
5
|
require 'google/protobuf'
|
6
6
|
|
7
7
|
require 'api/db/continue_list_pb'
|
8
|
+
require 'api/db/continue_scan_pb'
|
8
9
|
require 'api/db/delete_pb'
|
9
10
|
require 'api/db/get_pb'
|
10
11
|
require 'api/db/list_pb'
|
11
12
|
require 'api/db/put_pb'
|
13
|
+
require 'api/db/scan_pb'
|
12
14
|
require 'api/db/scan_root_paths_pb'
|
13
15
|
require 'api/db/sync_list_pb'
|
14
16
|
require 'api/db/transaction_pb'
|
15
17
|
|
16
18
|
|
17
|
-
descriptor_data = "\n\x10\x64\x62/service.proto\x12\nstately.db\x1a\x16\x64\x62/continue_list.proto\x1a\x0f\x64\x62/delete.proto\x1a\x0c\x64\x62/get.proto\x1a\rdb/list.proto\x1a\x0c\x64\x62/put.proto\x1a\x18\x64\x62/scan_root_paths.proto\x1a\x12\x64\x62/sync_list.proto\x1a\x14\x64\x62/transaction.proto2\
|
19
|
+
descriptor_data = "\n\x10\x64\x62/service.proto\x12\nstately.db\x1a\x16\x64\x62/continue_list.proto\x1a\x16\x64\x62/continue_scan.proto\x1a\x0f\x64\x62/delete.proto\x1a\x0c\x64\x62/get.proto\x1a\rdb/list.proto\x1a\x0c\x64\x62/put.proto\x1a\rdb/scan.proto\x1a\x18\x64\x62/scan_root_paths.proto\x1a\x12\x64\x62/sync_list.proto\x1a\x14\x64\x62/transaction.proto2\x8c\x06\n\x0f\x44\x61tabaseService\x12;\n\x03Put\x12\x16.stately.db.PutRequest\x1a\x17.stately.db.PutResponse\"\x03\x90\x02\x02\x12;\n\x03Get\x12\x16.stately.db.GetRequest\x1a\x17.stately.db.GetResponse\"\x03\x90\x02\x01\x12\x44\n\x06\x44\x65lete\x12\x19.stately.db.DeleteRequest\x1a\x1a.stately.db.DeleteResponse\"\x03\x90\x02\x02\x12J\n\tBeginList\x12\x1c.stately.db.BeginListRequest\x1a\x18.stately.db.ListResponse\"\x03\x90\x02\x01\x30\x01\x12P\n\x0c\x43ontinueList\x12\x1f.stately.db.ContinueListRequest\x1a\x18.stately.db.ListResponse\"\x03\x90\x02\x01\x30\x01\x12J\n\tBeginScan\x12\x1c.stately.db.BeginScanRequest\x1a\x18.stately.db.ListResponse\"\x03\x90\x02\x01\x30\x01\x12P\n\x0c\x43ontinueScan\x12\x1f.stately.db.ContinueScanRequest\x1a\x18.stately.db.ListResponse\"\x03\x90\x02\x01\x30\x01\x12L\n\x08SyncList\x12\x1b.stately.db.SyncListRequest\x1a\x1c.stately.db.SyncListResponse\"\x03\x90\x02\x01\x30\x01\x12T\n\x0bTransaction\x12\x1e.stately.db.TransactionRequest\x1a\x1f.stately.db.TransactionResponse\"\x00(\x01\x30\x01\x12Y\n\rScanRootPaths\x12 .stately.db.ScanRootPathsRequest\x1a!.stately.db.ScanRootPathsResponse\"\x03\x90\x02\x01\x42g\n\x0e\x63om.stately.dbB\x0cServiceProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
18
20
|
|
19
21
|
pool = Google::Protobuf::DescriptorPool.generated_pool
|
20
22
|
pool.add_serialized_file(descriptor_data)
|
@@ -62,6 +62,24 @@ module Stately
|
|
62
62
|
# ContinueList with its token should also be allowed.
|
63
63
|
# buf:lint:ignore RPC_RESPONSE_STANDARD_NAME
|
64
64
|
rpc :ContinueList, ::Stately::Db::ContinueListRequest, stream(::Stately::Db::ListResponse)
|
65
|
+
# BeginScan initiates a scan request which will scan over the entire store
|
66
|
+
# and apply the provided filters. This API returns a token that you can pass
|
67
|
+
# to ContinueScan to paginate through the result set. This can fail if the
|
68
|
+
# caller does not have permission to read Items.
|
69
|
+
# WARNING: THIS API CAN BE EXTREMELY EXPENSIVE FOR STORES WITH A LARGE NUMBER
|
70
|
+
# OF ITEMS.
|
71
|
+
# buf:lint:ignore RPC_RESPONSE_STANDARD_NAME
|
72
|
+
rpc :BeginScan, ::Stately::Db::BeginScanRequest, stream(::Stately::Db::ListResponse)
|
73
|
+
# ContinueScan takes the token from a BeginScan call and returns more results
|
74
|
+
# based on the original request parameters and pagination options. It has
|
75
|
+
# very few options of its own because it is a continuation of a previous list
|
76
|
+
# operation. It will return a new token which can be used for another
|
77
|
+
# ContinueScan call, and so on. Calls to ContinueScan are tied to the
|
78
|
+
# authorization of the original BeginScan call, so if the original BeginScan
|
79
|
+
# call was allowed, ContinueScan with its token should also be allowed.
|
80
|
+
# WARNING: THIS API CAN BE EXTREMELY EXPENSIVE FOR STORES WITH A LARGE NUMBER OF ITEMS.
|
81
|
+
# buf:lint:ignore RPC_RESPONSE_STANDARD_NAME
|
82
|
+
rpc :ContinueScan, ::Stately::Db::ContinueScanRequest, stream(::Stately::Db::ListResponse)
|
65
83
|
# SyncList returns all changes to Items within the result set of a previous
|
66
84
|
# List operation. For all Items within the result set that were modified, it
|
67
85
|
# returns the full Item at in its current state. It also returns a list of
|
@@ -24,17 +24,16 @@ module StatelyDB
|
|
24
24
|
# It will default to using the value of `STATELY_ACCESS_KEY` if
|
25
25
|
# no credentials are explicitly passed and will throw an error if no credentials are found.
|
26
26
|
class AuthTokenProvider < TokenProvider
|
27
|
-
# @param [String]
|
27
|
+
# @param [String] endpoint The endpoint of the auth server
|
28
28
|
# @param [String] access_key The StatelyDB access key credential
|
29
29
|
# @param [Float] base_retry_backoff_secs The base retry backoff in seconds
|
30
30
|
def initialize(
|
31
|
-
|
31
|
+
endpoint: "https://api.stately.cloud",
|
32
32
|
access_key: ENV.fetch("STATELY_ACCESS_KEY", nil),
|
33
33
|
base_retry_backoff_secs: 1
|
34
34
|
)
|
35
35
|
super()
|
36
|
-
@actor = Async::Actor.new(Actor.new(
|
37
|
-
base_retry_backoff_secs: base_retry_backoff_secs))
|
36
|
+
@actor = Async::Actor.new(Actor.new(endpoint:, access_key:, base_retry_backoff_secs:))
|
38
37
|
# this initialization cannot happen in the constructor because it is async and must run on the event loop
|
39
38
|
# which is not available in the constructor
|
40
39
|
@actor.init
|
@@ -55,10 +54,10 @@ module StatelyDB
|
|
55
54
|
# Actor for managing the token refresh
|
56
55
|
# This is designed to be used with Async::Actor and run on a dedicated thread.
|
57
56
|
class Actor
|
58
|
-
# @param [String]
|
57
|
+
# @param [String] endpoint The endpoint of the OAuth server
|
59
58
|
# @param [String] access_key The StatelyDB access key credential
|
60
59
|
# @param [Float] base_retry_backoff_secs The base retry backoff in seconds
|
61
|
-
def initialize(
|
60
|
+
def initialize(endpoint:, access_key:, base_retry_backoff_secs:)
|
62
61
|
super()
|
63
62
|
|
64
63
|
if access_key.nil?
|
@@ -72,7 +71,7 @@ module StatelyDB
|
|
72
71
|
end
|
73
72
|
|
74
73
|
@token_fetcher = StatelyDB::Common::Auth::StatelyAccessTokenFetcher.new(
|
75
|
-
|
74
|
+
endpoint: endpoint,
|
76
75
|
access_key: access_key,
|
77
76
|
base_retry_backoff_secs: base_retry_backoff_secs
|
78
77
|
)
|
@@ -48,14 +48,14 @@ module StatelyDB
|
|
48
48
|
].freeze
|
49
49
|
RETRY_ATTEMPTS = 10
|
50
50
|
|
51
|
-
# @param [String]
|
51
|
+
# @param [String] endpoint The endpoint of the OAuth server
|
52
52
|
# @param [String] access_key The StatelyDB access key credential
|
53
53
|
# @param [Float] base_retry_backoff_secs The base backoff time in seconds
|
54
|
-
def initialize(
|
54
|
+
def initialize(endpoint:, access_key:, base_retry_backoff_secs:)
|
55
55
|
super()
|
56
56
|
@access_key = access_key
|
57
57
|
@base_retry_backoff_secs = base_retry_backoff_secs
|
58
|
-
@channel = Common::Net.new_channel(endpoint:
|
58
|
+
@channel = Common::Net.new_channel(endpoint:)
|
59
59
|
error_interceptor = Common::ErrorInterceptor.new
|
60
60
|
@stub = Stately::Auth::AuthService::Stub.new(nil, nil, channel_override: @channel,
|
61
61
|
interceptors: [error_interceptor])
|
data/lib/common/net/conn.rb
CHANGED
@@ -24,13 +24,14 @@ module StatelyDB
|
|
24
24
|
# Find the full list of supported keys
|
25
25
|
# here: https://grpc.github.io/grpc/core/group__grpc__arg__keys.html
|
26
26
|
|
27
|
-
#
|
28
|
-
#
|
27
|
+
# Can't make it unlimited so set INT32_MAX: ~2GB
|
28
|
+
# https://groups.google.com/g/grpc-io/c/FoLNUJVN4o4
|
29
|
+
# We set max_ and absolute_max_ to the same value
|
29
30
|
# to stop the grpc lib changing the error code to ResourceExhausted
|
30
31
|
# while still successfully reading the metadata because only the soft
|
31
32
|
# limit was exceeded.
|
32
|
-
"grpc.max_metadata_size" =>
|
33
|
-
"grpc.absolute_max_metadata_size" =>
|
33
|
+
"grpc.max_metadata_size" => (2**31) - 1,
|
34
|
+
"grpc.absolute_max_metadata_size" => (2**31) - 1
|
34
35
|
}, creds)
|
35
36
|
end
|
36
37
|
end
|
data/lib/key_path.rb
CHANGED
data/lib/stately_codes.rb
CHANGED
@@ -47,6 +47,18 @@ module StatelyCode
|
|
47
47
|
# unless the conditions for the operation are changed.
|
48
48
|
CONDITIONAL_CHECK_FAILED = "ConditionalCheckFailed"
|
49
49
|
|
50
|
+
# ItemReusedWithDifferentKeyPath occurs when a client reads an Item, then
|
51
|
+
# attempts to write it with a different Key Path. Since writing an Item with
|
52
|
+
# a different Key Path will create a new Item, StatelyDB returns this error
|
53
|
+
# to prevent accidental copying of Items between different Key Paths. If you
|
54
|
+
# intend to move your original Item to a new Key Path, you should delete the
|
55
|
+
# original Item and create a new instance of the Item with the new Key Path.
|
56
|
+
# If you intend to create a new Item with the same data, you should create a
|
57
|
+
# new instance of the Item rather than reusing the read result.
|
58
|
+
#
|
59
|
+
# - Not Retryable
|
60
|
+
ITEM_REUSED_WITH_DIFFERENT_KEY_PATH = "ItemReusedWithDifferentKeyPath"
|
61
|
+
|
50
62
|
# NonRecoverableTransaction indicates that conditions required for the
|
51
63
|
# transaction to succeed are not possible to meet with the current state of
|
52
64
|
# the system. This can occur when an Item has more than one key-path, and is
|
data/lib/statelydb.rb
CHANGED
@@ -28,11 +28,14 @@ module StatelyDB
|
|
28
28
|
# @param token_provider [Common::Auth::TokenProvider] the token provider to use for authentication.
|
29
29
|
# @param endpoint [String] the endpoint to connect to.
|
30
30
|
# @param region [String] the region to connect to.
|
31
|
+
# @param no_auth [Boolean] Indicates that the client should not attempt to get
|
32
|
+
# an auth token. This is used when talking to the Stately BYOC Data Plane on localhost.
|
31
33
|
def initialize(store_id:,
|
32
34
|
schema:,
|
33
35
|
token_provider: Common::Auth::AuthTokenProvider.new,
|
34
36
|
endpoint: nil,
|
35
|
-
region: nil
|
37
|
+
region: nil,
|
38
|
+
no_auth: false)
|
36
39
|
if store_id.nil?
|
37
40
|
raise StatelyDB::Error.new("store_id is required",
|
38
41
|
code: GRPC::Core::StatusCodes::INVALID_ARGUMENT,
|
@@ -46,13 +49,14 @@ module StatelyDB
|
|
46
49
|
|
47
50
|
endpoint = self.class.make_endpoint(endpoint:, region:)
|
48
51
|
@channel = Common::Net.new_channel(endpoint:)
|
49
|
-
|
52
|
+
# Make sure to use the correct endpoint for the default token provider
|
53
|
+
@token_provider = token_provider || Common::Auth::AuthTokenProvider.new(endpoint:)
|
50
54
|
|
51
|
-
|
52
|
-
|
55
|
+
interceptors = [Common::ErrorInterceptor.new]
|
56
|
+
interceptors << Common::Auth::Interceptor.new(token_provider:) unless no_auth
|
53
57
|
|
54
|
-
@stub = Stately::Db::DatabaseService::Stub.new(nil, nil,
|
55
|
-
|
58
|
+
@stub = Stately::Db::DatabaseService::Stub.new(nil, nil,
|
59
|
+
channel_override: @channel, interceptors:)
|
56
60
|
@store_id = store_id.to_i
|
57
61
|
@schema = schema
|
58
62
|
@allow_stale = false
|
data/sig/statelydb.rbi
CHANGED
@@ -204,16 +204,19 @@ module StatelyDB
|
|
204
204
|
# _@param_ `endpoint` — the endpoint to connect to.
|
205
205
|
#
|
206
206
|
# _@param_ `region` — the region to connect to.
|
207
|
+
#
|
208
|
+
# _@param_ `no_auth` — Indicates that the client should not attempt to get an auth token. This is used when talking to the Stately BYOC Data Plane on localhost.
|
207
209
|
sig do
|
208
210
|
params(
|
209
211
|
store_id: Integer,
|
210
212
|
schema: Module,
|
211
213
|
token_provider: Common::Auth::TokenProvider,
|
212
214
|
endpoint: T.nilable(String),
|
213
|
-
region: T.nilable(String)
|
215
|
+
region: T.nilable(String),
|
216
|
+
no_auth: T::Boolean
|
214
217
|
).void
|
215
218
|
end
|
216
|
-
def initialize(store_id:, schema:, token_provider: Common::Auth::AuthTokenProvider.new, endpoint: nil, region: nil); end
|
219
|
+
def initialize(store_id:, schema:, token_provider: Common::Auth::AuthTokenProvider.new, endpoint: nil, region: nil, no_auth: false); end
|
217
220
|
|
218
221
|
# _@return_ — nil
|
219
222
|
sig { void }
|
@@ -618,13 +621,13 @@ module StatelyDB
|
|
618
621
|
].freeze, T.untyped)
|
619
622
|
RETRY_ATTEMPTS = T.let(10, T.untyped)
|
620
623
|
|
621
|
-
# _@param_ `
|
624
|
+
# _@param_ `endpoint` — The endpoint of the OAuth server
|
622
625
|
#
|
623
626
|
# _@param_ `access_key` — The StatelyDB access key credential
|
624
627
|
#
|
625
628
|
# _@param_ `base_retry_backoff_secs` — The base backoff time in seconds
|
626
|
-
sig { params(
|
627
|
-
def initialize(
|
629
|
+
sig { params(endpoint: String, access_key: String, base_retry_backoff_secs: Float).void }
|
630
|
+
def initialize(endpoint:, access_key:, base_retry_backoff_secs:); end
|
628
631
|
|
629
632
|
# Fetch a new token from the StatelyDB API
|
630
633
|
#
|
@@ -665,13 +668,13 @@ module StatelyDB
|
|
665
668
|
# It will default to using the value of `STATELY_ACCESS_KEY` if
|
666
669
|
# no credentials are explicitly passed and will throw an error if no credentials are found.
|
667
670
|
class AuthTokenProvider < StatelyDB::Common::Auth::TokenProvider
|
668
|
-
# _@param_ `
|
671
|
+
# _@param_ `endpoint` — The endpoint of the auth server
|
669
672
|
#
|
670
673
|
# _@param_ `access_key` — The StatelyDB access key credential
|
671
674
|
#
|
672
675
|
# _@param_ `base_retry_backoff_secs` — The base retry backoff in seconds
|
673
|
-
sig { params(
|
674
|
-
def initialize(
|
676
|
+
sig { params(endpoint: String, access_key: String, base_retry_backoff_secs: Float).void }
|
677
|
+
def initialize(endpoint: "https://api.stately.cloud", access_key: ENV.fetch("STATELY_ACCESS_KEY", nil), base_retry_backoff_secs: 1); end
|
675
678
|
|
676
679
|
# Close the token provider and kill any background operations
|
677
680
|
# This just invokes the close method on the actor which should do the cleanup
|
@@ -687,13 +690,13 @@ module StatelyDB
|
|
687
690
|
# Actor for managing the token refresh
|
688
691
|
# This is designed to be used with Async::Actor and run on a dedicated thread.
|
689
692
|
class Actor
|
690
|
-
# _@param_ `
|
693
|
+
# _@param_ `endpoint` — The endpoint of the OAuth server
|
691
694
|
#
|
692
695
|
# _@param_ `access_key` — The StatelyDB access key credential
|
693
696
|
#
|
694
697
|
# _@param_ `base_retry_backoff_secs` — The base retry backoff in seconds
|
695
|
-
sig { params(
|
696
|
-
def initialize(
|
698
|
+
sig { params(endpoint: String, access_key: String, base_retry_backoff_secs: Float).void }
|
699
|
+
def initialize(endpoint:, access_key:, base_retry_backoff_secs:); end
|
697
700
|
|
698
701
|
# Initialize the actor. This runs on the actor thread which means
|
699
702
|
# we can dispatch async operations here.
|
@@ -1099,6 +1102,9 @@ module Stately
|
|
1099
1102
|
ListPartialResult = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ListPartialResult").msgclass, T.untyped)
|
1100
1103
|
ListFinished = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ListFinished").msgclass, T.untyped)
|
1101
1104
|
SortDirection = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.SortDirection").enummodule, T.untyped)
|
1105
|
+
FilterCondition = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.FilterCondition").msgclass, T.untyped)
|
1106
|
+
BeginScanRequest = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.BeginScanRequest").msgclass, T.untyped)
|
1107
|
+
SegmentationParams = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.SegmentationParams").msgclass, T.untyped)
|
1102
1108
|
DeleteRequest = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.DeleteRequest").msgclass, T.untyped)
|
1103
1109
|
DeleteItem = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.DeleteItem").msgclass, T.untyped)
|
1104
1110
|
DeleteResult = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.DeleteResult").msgclass, T.untyped)
|
@@ -1124,6 +1130,7 @@ module Stately
|
|
1124
1130
|
TransactionFinished = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionFinished").msgclass, T.untyped)
|
1125
1131
|
ContinueListRequest = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ContinueListRequest").msgclass, T.untyped)
|
1126
1132
|
ContinueListDirection = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ContinueListDirection").enummodule, T.untyped)
|
1133
|
+
ContinueScanRequest = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ContinueScanRequest").msgclass, T.untyped)
|
1127
1134
|
SortableProperty = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.SortableProperty").enummodule, T.untyped)
|
1128
1135
|
ScanRootPathsRequest = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ScanRootPathsRequest").msgclass, T.untyped)
|
1129
1136
|
ScanRootPathsResponse = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ScanRootPathsResponse").msgclass, T.untyped)
|
@@ -1166,6 +1173,7 @@ module StatelyCode
|
|
1166
1173
|
CACHED_SCHEMA_TOO_OLD = T.let("CachedSchemaTooOld", T.untyped)
|
1167
1174
|
CONCURRENT_MODIFICATION = T.let("ConcurrentModification", T.untyped)
|
1168
1175
|
CONDITIONAL_CHECK_FAILED = T.let("ConditionalCheckFailed", T.untyped)
|
1176
|
+
ITEM_REUSED_WITH_DIFFERENT_KEY_PATH = T.let("ItemReusedWithDifferentKeyPath", T.untyped)
|
1169
1177
|
NON_RECOVERABLE_TRANSACTION = T.let("NonRecoverableTransaction", T.untyped)
|
1170
1178
|
STORE_IN_USE = T.let("StoreInUse", T.untyped)
|
1171
1179
|
STORE_REQUEST_LIMIT_EXCEEDED = T.let("StoreRequestLimitExceeded", T.untyped)
|
data/sig/statelydb.rbs
CHANGED
@@ -170,12 +170,15 @@ module StatelyDB
|
|
170
170
|
# _@param_ `endpoint` — the endpoint to connect to.
|
171
171
|
#
|
172
172
|
# _@param_ `region` — the region to connect to.
|
173
|
+
#
|
174
|
+
# _@param_ `no_auth` — Indicates that the client should not attempt to get an auth token. This is used when talking to the Stately BYOC Data Plane on localhost.
|
173
175
|
def initialize: (
|
174
176
|
store_id: Integer,
|
175
177
|
schema: Module,
|
176
178
|
?token_provider: Common::Auth::TokenProvider,
|
177
179
|
?endpoint: String?,
|
178
|
-
?region: String
|
180
|
+
?region: String?,
|
181
|
+
?no_auth: bool
|
179
182
|
) -> void
|
180
183
|
|
181
184
|
# _@return_ — nil
|
@@ -531,12 +534,12 @@ module StatelyDB
|
|
531
534
|
NON_RETRYABLE_ERRORS: untyped
|
532
535
|
RETRY_ATTEMPTS: untyped
|
533
536
|
|
534
|
-
# _@param_ `
|
537
|
+
# _@param_ `endpoint` — The endpoint of the OAuth server
|
535
538
|
#
|
536
539
|
# _@param_ `access_key` — The StatelyDB access key credential
|
537
540
|
#
|
538
541
|
# _@param_ `base_retry_backoff_secs` — The base backoff time in seconds
|
539
|
-
def initialize: (
|
542
|
+
def initialize: (endpoint: String, access_key: String, base_retry_backoff_secs: Float) -> void
|
540
543
|
|
541
544
|
# Fetch a new token from the StatelyDB API
|
542
545
|
#
|
@@ -572,12 +575,12 @@ module StatelyDB
|
|
572
575
|
# It will default to using the value of `STATELY_ACCESS_KEY` if
|
573
576
|
# no credentials are explicitly passed and will throw an error if no credentials are found.
|
574
577
|
class AuthTokenProvider < StatelyDB::Common::Auth::TokenProvider
|
575
|
-
# _@param_ `
|
578
|
+
# _@param_ `endpoint` — The endpoint of the auth server
|
576
579
|
#
|
577
580
|
# _@param_ `access_key` — The StatelyDB access key credential
|
578
581
|
#
|
579
582
|
# _@param_ `base_retry_backoff_secs` — The base retry backoff in seconds
|
580
|
-
def initialize: (?
|
583
|
+
def initialize: (?endpoint: String, ?access_key: String, ?base_retry_backoff_secs: Float) -> void
|
581
584
|
|
582
585
|
# Close the token provider and kill any background operations
|
583
586
|
# This just invokes the close method on the actor which should do the cleanup
|
@@ -591,12 +594,12 @@ module StatelyDB
|
|
591
594
|
# Actor for managing the token refresh
|
592
595
|
# This is designed to be used with Async::Actor and run on a dedicated thread.
|
593
596
|
class Actor
|
594
|
-
# _@param_ `
|
597
|
+
# _@param_ `endpoint` — The endpoint of the OAuth server
|
595
598
|
#
|
596
599
|
# _@param_ `access_key` — The StatelyDB access key credential
|
597
600
|
#
|
598
601
|
# _@param_ `base_retry_backoff_secs` — The base retry backoff in seconds
|
599
|
-
def initialize: (
|
602
|
+
def initialize: (endpoint: String, access_key: String, base_retry_backoff_secs: Float) -> void
|
600
603
|
|
601
604
|
# Initialize the actor. This runs on the actor thread which means
|
602
605
|
# we can dispatch async operations here.
|
@@ -953,6 +956,9 @@ module Stately
|
|
953
956
|
ListPartialResult: untyped
|
954
957
|
ListFinished: untyped
|
955
958
|
SortDirection: untyped
|
959
|
+
FilterCondition: untyped
|
960
|
+
BeginScanRequest: untyped
|
961
|
+
SegmentationParams: untyped
|
956
962
|
DeleteRequest: untyped
|
957
963
|
DeleteItem: untyped
|
958
964
|
DeleteResult: untyped
|
@@ -978,6 +984,7 @@ module Stately
|
|
978
984
|
TransactionFinished: untyped
|
979
985
|
ContinueListRequest: untyped
|
980
986
|
ContinueListDirection: untyped
|
987
|
+
ContinueScanRequest: untyped
|
981
988
|
SortableProperty: untyped
|
982
989
|
ScanRootPathsRequest: untyped
|
983
990
|
ScanRootPathsResponse: untyped
|
@@ -1020,6 +1027,7 @@ module StatelyCode
|
|
1020
1027
|
CACHED_SCHEMA_TOO_OLD: untyped
|
1021
1028
|
CONCURRENT_MODIFICATION: untyped
|
1022
1029
|
CONDITIONAL_CHECK_FAILED: untyped
|
1030
|
+
ITEM_REUSED_WITH_DIFFERENT_KEY_PATH: untyped
|
1023
1031
|
NON_RECOVERABLE_TRANSACTION: untyped
|
1024
1032
|
STORE_IN_USE: untyped
|
1025
1033
|
STORE_REQUEST_LIMIT_EXCEEDED: untyped
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: statelydb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stately Cloud, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|
@@ -72,11 +72,13 @@ executables: []
|
|
72
72
|
extensions: []
|
73
73
|
extra_rdoc_files: []
|
74
74
|
files:
|
75
|
+
- LICENSE.txt
|
75
76
|
- README.md
|
76
77
|
- lib/api/auth/get_auth_token_pb.rb
|
77
78
|
- lib/api/auth/service_pb.rb
|
78
79
|
- lib/api/auth/service_services_pb.rb
|
79
80
|
- lib/api/db/continue_list_pb.rb
|
81
|
+
- lib/api/db/continue_scan_pb.rb
|
80
82
|
- lib/api/db/delete_pb.rb
|
81
83
|
- lib/api/db/get_pb.rb
|
82
84
|
- lib/api/db/item_pb.rb
|
@@ -84,6 +86,7 @@ files:
|
|
84
86
|
- lib/api/db/list_pb.rb
|
85
87
|
- lib/api/db/list_token_pb.rb
|
86
88
|
- lib/api/db/put_pb.rb
|
89
|
+
- lib/api/db/scan_pb.rb
|
87
90
|
- lib/api/db/scan_root_paths_pb.rb
|
88
91
|
- lib/api/db/service_pb.rb
|
89
92
|
- lib/api/db/service_services_pb.rb
|