Class: StatelyDB::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/statelydb.rb

Overview

Client is a client for interacting with the Stately Cloud API.

Instance Method Summary collapse

Constructor Details

#initialize(store_id: nil, schema: StatelyDB::Types, token_provider: Common::Auth::Auth0TokenProvider.new, channel: Common::Net.new_channel) ⇒ Client

Initialize a new StatelyDB Client

Parameters:

  • store_id (Integer) (defaults to: nil)

    the StatelyDB to use for all operations with this client.

  • schema (Module) (defaults to: StatelyDB::Types)

    the schema module to use for mapping StatelyDB Items.

  • token_provider (Common::Auth::TokenProvider) (defaults to: Common::Auth::Auth0TokenProvider.new)

    the token provider to use for authentication.

  • channel (GRPC::Core::Channel) (defaults to: Common::Net.new_channel)

    the gRPC channel to use for communication.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/statelydb.rb', line 33

def initialize(store_id: nil,
               schema: StatelyDB::Types,
               token_provider: Common::Auth::Auth0TokenProvider.new,
               channel: Common::Net.new_channel)
  raise "store_id is required" if store_id.nil?
  raise "schema is required" if schema.nil?

  auth_interceptor = Common::Auth::Interceptor.new(token_provider:)
  error_interceptor = Common::ErrorInterceptor.new

  @stub = Stately::Db::DatabaseService::Stub.new(nil, nil, channel_override: channel,
                                                           interceptors: [error_interceptor, auth_interceptor])
  @store_id = store_id.to_i
  @schema = schema
  @allow_stale = false
end

Instance Method Details

#begin_list(prefix, limit: 100, sort_property: nil, sort_direction: :ascending) ⇒ Array<StatelyDB::Item>, StatelyDB::Token

Begin listing Items from a StatelyDB Store at the given prefix.

Examples:

client.data.begin_list("/ItemType-identifier", limit: 10, sort_direction: :ascending)

Parameters:

  • prefix (String)

    the prefix to list

  • limit (Integer) (defaults to: 100)

    the maximum number of items to return

  • sort_property (String) (defaults to: nil)

    the property to sort by

  • sort_direction (Symbol) (defaults to: :ascending)

    the direction to sort by (:ascending or :descending)

Returns:



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/statelydb.rb', line 110

def begin_list(prefix,
               limit: 100,
               sort_property: nil,
               sort_direction: :ascending)
  sort_direction = sort_direction == :ascending ? 0 : 1

  req = Stately::Db::BeginListRequest.new(
    store_id: @store_id,
    key_path_prefix: String(prefix),
    limit:,
    sort_property:,
    sort_direction:,
    allow_stale: @allow_stale
  )
  resp = @stub.begin_list(req)
  process_list_response(resp)
end

#continue_list(token) ⇒ Array<StatelyDB::Item>, StatelyDB::Token

Continue listing Items from a StatelyDB Store using a token.

Examples:

(items, token) = client.data.begin_list("/ItemType-identifier")
client.data.continue_list(token)

Parameters:

Returns:



136
137
138
139
140
141
142
# File 'lib/statelydb.rb', line 136

def continue_list(token)
  req = Stately::Db::ContinueListRequest.new(
    token_data: token.token_data
  )
  resp = @stub.continue_list(req)
  process_list_response(resp)
end

#delete(*key_paths) ⇒ void

This method returns an undefined value.

Delete one or more Items from a StatelyDB Store at the given key_paths.

Examples:

client.data.delete("/ItemType-identifier", "/ItemType-identifier2")

Parameters:

  • key_paths (String, Array<String>)

    the paths to the items

Raises:

  • (StatelyDB::Error::InvalidParameters)

    if the parameters are invalid

  • (StatelyDB::Error::NotFound)

    if the item is not found



207
208
209
210
211
212
213
214
215
# File 'lib/statelydb.rb', line 207

def delete(*key_paths)
  key_paths = Array(key_paths).flatten
  req = Stately::Db::DeleteRequest.new(
    store_id: @store_id,
    deletes: key_paths.map { |key_path| Stately::Db::DeleteItem.new(key_path: String(key_path)) }
  )
  @stub.delete(req)
  nil
end

#get(key_path) ⇒ StatelyDB::Item, NilClass

Fetch a single Item from a StatelyDB Store at the given key_path.

Examples:

client.get("/ItemType-identifier")

Parameters:

  • key_path (String)

    the path to the item

Returns:

Raises:

  • (StatelyDB::Error)

    if the parameters are invalid or if the item is not found



70
71
72
73
74
75
# File 'lib/statelydb.rb', line 70

def get(key_path)
  resp = get_batch(key_path)

  # Always return a single Item.
  resp.first
end

#get_batch(*key_paths) ⇒ Array<StatelyDB::Item>, NilClass

Fetch a batch of Items from a StatelyDB Store at the given key_paths.

Examples:

client.data.get_batch("/ItemType-identifier", "/ItemType-identifier2")

Parameters:

  • key_paths (String, Array<String>)

    the paths to the items

Returns:

Raises:

  • (StatelyDB::Error)

    if the parameters are invalid or if the item is not found



85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/statelydb.rb', line 85

def get_batch(*key_paths)
  key_paths = Array(key_paths).flatten
  req = Stately::Db::GetRequest.new(
    store_id: @store_id,
    gets:
      key_paths.map { |key_path| Stately::Db::GetItem.new(key_path: String(key_path)) },
    allow_stale: @allow_stale
  )

  resp = @stub.get(req)
  resp.items.map do |result|
    @schema.unmarshal_item(stately_item: result)
  end
end

#put(item) ⇒ StatelyDB::Item

Put an Item into a StatelyDB Store at the given key_path.

Examples:

client.data.put(my_item)

Parameters:

Returns:



167
168
169
170
171
172
# File 'lib/statelydb.rb', line 167

def put(item)
  resp = put_batch(item)

  # Always return a single Item.
  resp.first
end

#put_batch(*items) ⇒ Array<StatelyDB::Item>

Put a batch of Items into a StatelyDB Store.

Examples:

client.data.put_batch(item1, item2)

Parameters:

Returns:



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/statelydb.rb', line 181

def put_batch(*items)
  items = Array(items).flatten
  req = Stately::Db::PutRequest.new(
    store_id: @store_id,
    puts: items.map do |item|
      Stately::Db::PutItem.new(
        item: item.send("marshal_stately")
      )
    end
  )
  resp = @stub.put(req)

  resp.items.map do |result|
    @schema.unmarshal_item(stately_item: result)
  end
end

#sync_list(token) ⇒ StatelyDB::SyncResult

Sync a list of Items from a StatelyDB Store.

Examples:

(items, token) = client.data.begin_list("/ItemType-identifier")
client.data.sync_list(token)

Parameters:

Returns:



152
153
154
155
156
157
158
# File 'lib/statelydb.rb', line 152

def sync_list(token)
  req = Stately::Db::SyncListRequest.new(
    token_data: token.token_data
  )
  resp = @stub.sync_list(req)
  process_sync_response(resp)
end

#transactionStatelyDB::Transaction::Transaction::Result

Transaction takes a block and executes the block within a transaction. If the block raises an exception, the transaction is rolled back. If the block completes successfully, the transaction is committed.

Examples:

client.data.transaction do |txn|
  txn.put(item: my_item)
  txn.put(item: another_item)
end

Returns:

Raises:

  • (StatelyDB::Error::InvalidParameters)

    if the parameters are invalid

  • (StatelyDB::Error::NotFound)

    if the item is not found

  • (Exception)

    if any other exception is raised



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/statelydb.rb', line 231

def transaction
  txn = StatelyDB::Transaction::Transaction.new(stub: @stub, store_id: @store_id, schema: @schema)
  txn.begin
  yield txn
  txn.commit
rescue StatelyDB::Error
  raise
# Handle any other exceptions and abort the transaction. We're rescuing Exception here
# because we want to catch all exceptions, including those that don't inherit from StandardError.
rescue Exception => e
  txn.abort

  # All gRPC errors inherit from GRPC::BadStatus. We wrap these in a StatelyDB::Error.
  raise StatelyDB::Error.from(e) if e.is_a? GRPC::BadStatus

  # Calling raise with no parameters re-raises the original exception
  raise
end

#with_allow_stale(allow_stale) ⇒ StatelyDB::Client

Set whether to allow stale results for all operations with this client. This produces a new client with the allow_stale flag set.

Examples:

client.with_allow_stale(true).get("/ItemType-identifier")

Parameters:

  • allow_stale (Boolean)

    whether to allow stale results

Returns:



56
57
58
59
60
# File 'lib/statelydb.rb', line 56

def with_allow_stale(allow_stale)
  new_client = clone
  new_client.instance_variable_set(:@allow_stale, allow_stale)
  new_client
end