Module: ActiveModel::Datastore::ClassMethods
- Defined in:
- lib/active_model/datastore.rb
Overview
Methods defined here will be class methods when ‘include ActiveModel::Datastore’.
Instance Method Summary collapse
-
#all(options = {}) ⇒ Array<Model>, String
Queries entities from Cloud Datastore by named kind and using the provided options.
-
#build_query(options = {}) ⇒ Query
Constructs a Google::Cloud::Datastore::Query.
- #exclude_from_index(entity, boolean) ⇒ Object
-
#find(*ids, parent: nil) ⇒ Model, ...
Find entity by id - this can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
-
#find_all_entities(ids_or_names, parent) ⇒ Object
Finds entities by keys using the provided array items.
-
#find_by(args) ⇒ Model?
Finds the first entity matching the specified condition.
-
#find_entities(*ids_or_names, parent: nil) ⇒ Array<Entity>
Retrieves the entities for the provided ids by key and by an optional parent.
-
#find_entity(id_or_name, parent = nil) ⇒ Entity?
Retrieves an entity by id or name and by an optional parent.
-
#from_entities(entities) ⇒ Object
Translates an Enumerator of Datastore::Entity objects to ActiveModel::Model objects.
-
#from_entity(entity) ⇒ Model
Translates between Datastore::Entity objects and ActiveModel::Model objects.
- #log_google_cloud_error ⇒ Object
-
#query_options(query, options) ⇒ Object
**************** private ****************.
-
#query_property_filter(query, options) ⇒ Object
Adds property filters to the query if included in the options.
-
#query_sort(query, options) ⇒ Object
Adds sorting to the results by a property name if included in the options.
- #retry_on_exception(max_retry_count = 5) ⇒ Object
- #retry_on_exception?(max_retry_count = 5) ⇒ Boolean
Instance Method Details
#all(options = {}) ⇒ Array<Model>, String
Queries entities from Cloud Datastore by named kind and using the provided options. When a limit option is provided queries up to the limit and returns results with a cursor.
This method may make several API calls until all query results are retrieved. The ‘run` method returns a QueryResults object, which is a special case Array with additional values. QueryResults are returned in batches, and the batch size is determined by the Datastore API. Batch size is not guaranteed. It will be affected by the size of the data being returned, and by other forces such as how distributed and/or consistent the data in Datastore is. Calling `all` on the QueryResults retrieves all results by repeatedly loading #next until #next? returns false. The `all` method returns an enumerator which from_entities iterates on.
Be sure to use as narrow a search criteria as possible. Please use with caution.
or if options was provided:
311 312 313 314 315 316 317 318 319 320 |
# File 'lib/active_model/datastore.rb', line 311 def all( = {}) next_cursor = nil query = build_query() query_results = retry_on_exception { CloudDatastore.dataset.run query } if [:limit] next_cursor = query_results.cursor if query_results.size == [:limit] return from_entities(query_results.all), next_cursor end from_entities(query_results.all) end |
#build_query(options = {}) ⇒ Query
Constructs a Google::Cloud::Datastore::Query.
423 424 425 426 |
# File 'lib/active_model/datastore.rb', line 423 def build_query( = {}) query = CloudDatastore.dataset.query name (query, ) end |
#exclude_from_index(entity, boolean) ⇒ Object
401 402 403 404 405 |
# File 'lib/active_model/datastore.rb', line 401 def exclude_from_index(entity, boolean) entity.properties.to_h.keys.each do |value| entity.exclude_from_indexes! value, boolean end end |
#find(*ids, parent: nil) ⇒ Model, ...
Find entity by id - this can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). The parent key is optional.
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
# File 'lib/active_model/datastore.rb', line 332 def find(*ids, parent: nil) expects_array = ids.first.is_a?(Array) ids = ids.flatten.compact.uniq.map(&:to_i) case ids.size when 0 raise EntityError, "Couldn't find #{name} without an ID" when 1 entity = find_entity(ids.first, parent) model_entity = from_entity(entity) expects_array ? [model_entity].compact : model_entity else lookup_results = find_all_entities(ids, parent) from_entities(lookup_results.all) end end |
#find_all_entities(ids_or_names, parent) ⇒ Object
Finds entities by keys using the provided array items. Results provided by the dataset ‘find_all` is a Dataset::LookupResults object.
513 514 515 516 517 |
# File 'lib/active_model/datastore.rb', line 513 def find_all_entities(ids_or_names, parent) keys = ids_or_names.map { |id| CloudDatastore.dataset.key name, id } keys.map { |key| key.parent = parent } if parent.present? retry_on_exception { CloudDatastore.dataset.find_all keys } end |
#find_by(args) ⇒ Model?
Finds the first entity matching the specified condition.
361 362 363 364 365 366 367 368 |
# File 'lib/active_model/datastore.rb', line 361 def find_by(args) query = CloudDatastore.dataset.query name query.ancestor(args[:ancestor]) if args[:ancestor] query.limit(1) query.where(args.keys[0].to_s, '=', args.values[0]) query_results = retry_on_exception { CloudDatastore.dataset.run query } from_entity(query_results.first) end |
#find_entities(*ids_or_names, parent: nil) ⇒ Array<Entity>
Retrieves the entities for the provided ids by key and by an optional parent. The find_all method returns LookupResults, which is a special case Array with additional values. LookupResults are returned in batches, and the batch size is determined by the Datastore API. Batch size is not guaranteed. It will be affected by the size of the data being returned, and by other forces such as how distributed and/or consistent the data in Datastore is. Calling ‘all` on the LookupResults retrieves all results by repeatedly loading #next until #next? returns false. The `all` method returns an enumerator unless passed a block. We iterate on the enumerator to return the model entity objects.
273 274 275 276 277 |
# File 'lib/active_model/datastore.rb', line 273 def find_entities(*ids_or_names, parent: nil) ids_or_names = ids_or_names.flatten.compact.uniq lookup_results = find_all_entities(ids_or_names, parent) lookup_results.all.collect { |x| x } end |
#find_entity(id_or_name, parent = nil) ⇒ Entity?
Retrieves an entity by id or name and by an optional parent.
251 252 253 254 255 |
# File 'lib/active_model/datastore.rb', line 251 def find_entity(id_or_name, parent = nil) key = CloudDatastore.dataset.key name, id_or_name key.parent = parent if parent.present? retry_on_exception { CloudDatastore.dataset.find key } end |
#from_entities(entities) ⇒ Object
Translates an Enumerator of Datastore::Entity objects to ActiveModel::Model objects.
Results provided by the dataset ‘find_all` or `run query` will be a Dataset::LookupResults or Dataset::QueryResults object. Invoking `all` on those objects returns an enumerator.
378 379 380 381 |
# File 'lib/active_model/datastore.rb', line 378 def from_entities(entities) raise ArgumentError, 'Entities param must be an Enumerator' unless entities.is_a? Enumerator entities.map { |entity| from_entity(entity) } end |
#from_entity(entity) ⇒ Model
Translates between Datastore::Entity objects and ActiveModel::Model objects.
389 390 391 392 393 394 395 396 397 398 399 |
# File 'lib/active_model/datastore.rb', line 389 def from_entity(entity) return if entity.nil? model_entity = new model_entity.id = entity.key.id unless entity.key.id.nil? model_entity.id = entity.key.name unless entity.key.name.nil? entity.properties.to_hash.each do |name, value| model_entity.send "#{name}=", value if model_entity.respond_to? "#{name}=" end model_entity.reload! model_entity end |
#log_google_cloud_error ⇒ Object
460 461 462 463 464 465 |
# File 'lib/active_model/datastore.rb', line 460 def log_google_cloud_error yield rescue Google::Cloud::Error => e puts "\e[33m[#{e..inspect}]\e[0m" raise e end |
#query_options(query, options) ⇒ Object
**************** private ****************
469 470 471 472 473 474 475 476 |
# File 'lib/active_model/datastore.rb', line 469 def (query, ) query.ancestor([:ancestor]) if [:ancestor] query.cursor([:cursor]) if [:cursor] query.limit([:limit]) if [:limit] query_sort(query, ) query.select([:select]) if [:select] query_property_filter(query, ) end |
#query_property_filter(query, options) ⇒ Object
Adds property filters to the query if included in the options. Accepts individual or nested Arrays:
[['superseded', '=', false], ['email', '=', 'something']]
492 493 494 495 496 497 498 499 500 501 502 503 504 |
# File 'lib/active_model/datastore.rb', line 492 def query_property_filter(query, ) if [:where] opts = [:where] if opts[0].is_a?(Array) opts.each do |opt| query.where(opt[0], opt[1], opt[2]) unless opt.nil? end else query.where(opts[0], opts[1], opts[2]) end end query end |
#query_sort(query, options) ⇒ Object
Adds sorting to the results by a property name if included in the options.
481 482 483 484 485 |
# File 'lib/active_model/datastore.rb', line 481 def query_sort(query, ) query.order([:order]) if [:order] query.order([:desc_order], :desc) if [:desc_order] query end |
#retry_on_exception(max_retry_count = 5) ⇒ Object
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 |
# File 'lib/active_model/datastore.rb', line 444 def retry_on_exception(max_retry_count = 5) retries = 0 sleep_time = 0.25 begin yield rescue => e raise e if retries >= max_retry_count puts "\e[33mRescued exception #{e..inspect}, retrying in #{sleep_time}\e[0m" # 0.25, 0.5, 1, 2, and 4 second between retries. sleep sleep_time retries += 1 sleep_time *= 2 retry end end |
#retry_on_exception?(max_retry_count = 5) ⇒ Boolean
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 |
# File 'lib/active_model/datastore.rb', line 428 def retry_on_exception?(max_retry_count = 5) retries = 0 sleep_time = 0.25 begin yield rescue => e return false if retries >= max_retry_count puts "\e[33mRescued exception #{e..inspect}, retrying in #{sleep_time}\e[0m" # 0.25, 0.5, 1, 2, and 4 second between retries. sleep sleep_time retries += 1 sleep_time *= 2 retry end end |