Class: Kagaribi::Collection

Inherits:
Object
  • Object
show all
Defined in:
lib/kagaribi/collection.rb,
sig/kagaribi/collection.rbs

Overview

Manage a Firestore collection

Examples:

require "kagaribi"

collection = Kagaribi.collection("users")

# or

class UsersCollection < Kagaribi::Collection
  def initialize
    super("users")
  end
end
collection = UsersCollection.new

collection.set("sue445", name: "sue445", url: "https://github.com/sue445")
#=> document is stored in a key named "users/sue445" to Firestore collection

collection.get("sue445")
#=> { name: "sue445", url: "https://github.com/sue445" }

Constant Summary collapse

MAX_RETRY_COUNT =

Returns:

  • (Integer)
5

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(collection_name, database_id: nil, logger: nil) ⇒ Collection

Returns a new instance of Collection.

Parameters:

  • collection_name (String)
  • database_id (String, nil) (defaults to: nil)

    Identifier for a Firestore database. If not present, the default database of the project is used.

  • logger (Logger, nil) (defaults to: nil)

    default is STDOUT Logger

  • database_id: (string, nil) (defaults to: nil)
  • logger: (Logger, nil) (defaults to: nil)


43
44
45
46
47
48
49
50
51
52
53
# File 'lib/kagaribi/collection.rb', line 43

def initialize(collection_name, database_id: nil, logger: nil)
  @collection_name = collection_name
  @database_id = database_id

  @logger =
    if logger
      logger
    else
      Logger.new($stdout)
    end
end

Instance Attribute Details

#collection_nameString (readonly)

Returns:

  • (String)


30
31
32
# File 'lib/kagaribi/collection.rb', line 30

def collection_name
  @collection_name
end

#database_idString? (readonly)

Returns:

  • (String, nil)


34
35
36
# File 'lib/kagaribi/collection.rb', line 34

def database_id
  @database_id
end

#loggerLogger (readonly)

Returns:

  • (Logger)


38
39
40
# File 'lib/kagaribi/collection.rb', line 38

def logger
  @logger
end

Class Method Details

.sanitize_key(key) ⇒ String

Parameters:

  • key (String)

Returns:

  • (String)


110
111
112
# File 'lib/kagaribi/collection.rb', line 110

def self.sanitize_key(key)
  key.tr("/", "-")
end

Instance Method Details

#delete(doc_key)

This method returns an undefined value.

Delete document in collection

Parameters:

  • doc_key (String)


101
102
103
104
105
106
# File 'lib/kagaribi/collection.rb', line 101

def delete(doc_key)
  with_retry("Kagaribi::Collection#delete") do
    ref = firestore.doc(full_doc_key(doc_key))
    ref.delete
  end
end

#exists?(doc_key) ⇒ Boolean?

Whether document exists in collection

Parameters:

  • doc_key (String)

Returns:

  • (Boolean, nil)


91
92
93
94
95
96
97
# File 'lib/kagaribi/collection.rb', line 91

def exists?(doc_key)
  with_retry("Kagaribi::Collection#exists?") do
    ref = firestore.doc(full_doc_key(doc_key))
    snap = ref.get
    snap&.exists?
  end
end

#firestoreGoogle::Cloud::Firestore

Returns:

  • (Google::Cloud::Firestore)


117
118
119
# File 'lib/kagaribi/collection.rb', line 117

def firestore
  @firestore ||= Google::Cloud::Firestore.new(database_id: database_id)
end

#full_doc_key(doc_key) ⇒ String

Parameters:

  • doc_key (String)

Returns:

  • (String)


134
135
136
# File 'lib/kagaribi/collection.rb', line 134

def full_doc_key(doc_key)
  "#{sanitized_collection_name}/#{sanitize_key(doc_key)}"
end

#get(doc_key) ⇒ Hash<Symbol,Object>

Get document from collection

Parameters:

  • doc_key (String)

Returns:

  • (Hash<Symbol,Object>)

    return empty Hash if document isn't found



80
81
82
83
84
85
86
# File 'lib/kagaribi/collection.rb', line 80

def get(doc_key)
  with_retry("Kagaribi::Collection#get") do
    ref = firestore.doc(full_doc_key(doc_key))
    snap = ref.get
    snap&.data || {}
  end
end

#retryable_error?(error) ⇒ Boolean

Parameters:

  • error (StandardError)

Returns:

  • (Boolean)


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/kagaribi/collection.rb', line 157

def retryable_error?(error)
  case error
  when RuntimeError
    # e.g.
    # Could not load the default credentials. Browse to
    # https://developers.google.com/accounts/docs/application-default-credentials
    # for more information
    return true if error.message.include?("Could not load the default credentials.")

    # e.g.
    # Your credentials were not found. To set up Application Default
    # Credentials for your environment, see
    # https://cloud.google.com/docs/authentication/external/set-up-adc
    return true if error.message.include?("Your credentials were not found.")

    return false
  end

  true
end

#sanitize_key(key) ⇒ String

Parameters:

  • key (String)

Returns:

  • (String)


128
129
130
# File 'lib/kagaribi/collection.rb', line 128

def sanitize_key(key)
  Collection.sanitize_key(key)
end

#sanitized_collection_nameString

Returns:

  • (String)


122
123
124
# File 'lib/kagaribi/collection.rb', line 122

def sanitized_collection_name
  sanitize_key(@collection_name)
end

#set(doc_key, data)

Note:

If a document with the same key exists, it is overwritten.

This method returns an undefined value.

Save a document to collection

Parameters:

  • doc_key (String)
  • data (Hash)


59
60
61
62
63
64
# File 'lib/kagaribi/collection.rb', line 59

def set(doc_key, data)
  with_retry("Kagaribi::Collection#set") do
    ref = firestore.doc(full_doc_key(doc_key))
    ref.set(data)
  end
end

#update(doc_key, data)

Note:

If a document with the same key exists, it is merged.

This method returns an undefined value.

Update a document that has already been saved

Parameters:

  • doc_key (String)
  • data (Hash)


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

def update(doc_key, data)
  with_retry("Kagaribi::Collection#update") do
    ref = firestore.doc(full_doc_key(doc_key))
    ref.update(data)
  end
end

#with_retry(label) { ... }

This method returns an undefined value.

Parameters:

  • label (String)

Yields:



140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/kagaribi/collection.rb', line 140

def with_retry(label)
  yield
rescue TypeError, GRPC::Unavailable, RuntimeError, Signet::AuthorizationError, Google::Cloud::UnauthenticatedError => error
  raise error unless retryable_error?(error)

  retry_count ||= 0
  retry_count += 1

  raise error if retry_count > MAX_RETRY_COUNT

  logger.warn "[#{label}] collection_name=#{@collection_name}, retry_count=#{retry_count}, error=#{error}"
  sleep 1
  retry
end