gcloud 0.8.2 → 0.9.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 +8 -8
- data/CHANGELOG.md +26 -0
- data/OVERVIEW.md +10 -8
- data/lib/gcloud.rb +12 -13
- data/lib/gcloud/bigquery/dataset/list.rb +2 -4
- data/lib/gcloud/bigquery/job/list.rb +3 -5
- data/lib/gcloud/bigquery/table/list.rb +3 -5
- data/lib/gcloud/datastore.rb +326 -97
- data/lib/gcloud/datastore/commit.rb +73 -56
- data/lib/gcloud/datastore/credentials.rb +1 -12
- data/lib/gcloud/datastore/cursor.rb +76 -0
- data/lib/gcloud/datastore/dataset.rb +337 -134
- data/lib/gcloud/datastore/dataset/lookup_results.rb +12 -12
- data/lib/gcloud/datastore/dataset/query_results.rb +117 -27
- data/lib/gcloud/datastore/entity.rb +159 -93
- data/lib/gcloud/datastore/errors.rb +0 -21
- data/lib/gcloud/datastore/gql_query.rb +211 -0
- data/lib/gcloud/datastore/grpc_utils.rb +131 -0
- data/lib/gcloud/datastore/key.rb +74 -65
- data/lib/gcloud/datastore/properties.rb +14 -1
- data/lib/gcloud/datastore/query.rb +188 -52
- data/lib/gcloud/datastore/service.rb +161 -0
- data/lib/gcloud/datastore/transaction.rb +175 -60
- data/lib/gcloud/dns/change/list.rb +2 -4
- data/lib/gcloud/dns/record/list.rb +2 -4
- data/lib/gcloud/dns/zone/list.rb +2 -4
- data/lib/gcloud/grpc_utils.rb +11 -0
- data/lib/gcloud/logging/entry.rb +6 -17
- data/lib/gcloud/logging/entry/list.rb +8 -9
- data/lib/gcloud/logging/metric/list.rb +4 -5
- data/lib/gcloud/logging/resource.rb +1 -12
- data/lib/gcloud/logging/resource_descriptor.rb +9 -12
- data/lib/gcloud/logging/resource_descriptor/list.rb +4 -5
- data/lib/gcloud/logging/sink/list.rb +4 -5
- data/lib/gcloud/pubsub/message.rb +1 -3
- data/lib/gcloud/pubsub/subscription.rb +5 -7
- data/lib/gcloud/pubsub/topic.rb +1 -3
- data/lib/gcloud/resource_manager/project/list.rb +2 -4
- data/lib/gcloud/translate/api.rb +5 -3
- data/lib/gcloud/translate/connection.rb +4 -4
- data/lib/gcloud/version.rb +1 -1
- metadata +9 -20
- data/lib/gcloud/datastore/connection.rb +0 -203
- data/lib/gcloud/datastore/proto.rb +0 -266
- data/lib/gcloud/proto/datastore_v1.pb.rb +0 -377
- data/lib/google/protobuf/any.rb +0 -17
- data/lib/google/protobuf/api.rb +0 -31
- data/lib/google/protobuf/duration.rb +0 -17
- data/lib/google/protobuf/empty.rb +0 -15
- data/lib/google/protobuf/field_mask.rb +0 -16
- data/lib/google/protobuf/source_context.rb +0 -16
- data/lib/google/protobuf/struct.rb +0 -35
- data/lib/google/protobuf/timestamp.rb +0 -17
- data/lib/google/protobuf/type.rb +0 -79
- data/lib/google/protobuf/wrappers.rb +0 -48
| @@ -22,21 +22,23 @@ module Gcloud | |
| 22 22 | 
             
                # in a single commit.
         | 
| 23 23 | 
             
                #
         | 
| 24 24 | 
             
                # @example
         | 
| 25 | 
            -
                #    | 
| 25 | 
            +
                #   gcloud = Gcloud.new
         | 
| 26 | 
            +
                #   datastore = gcloud.datastore
         | 
| 27 | 
            +
                #   datastore.commit do |c|
         | 
| 26 28 | 
             
                #     c.save task1, task2
         | 
| 27 29 | 
             
                #     c.delete entity1, entity2
         | 
| 28 30 | 
             
                #   end
         | 
| 29 31 | 
             
                #
         | 
| 30 | 
            -
                #  | 
| 31 | 
            -
                # {Gcloud::Datastore::Transaction#commit} | 
| 32 | 
            -
                #
         | 
| 32 | 
            +
                # @see {Gcloud::Datastore::Dataset#commit}
         | 
| 33 | 
            +
                # @see {Gcloud::Datastore::Transaction#commit}
         | 
| 33 34 | 
             
                class Commit
         | 
| 34 35 | 
             
                  ##
         | 
| 35 36 | 
             
                  # @private Create a new Commit object.
         | 
| 36 37 | 
             
                  def initialize
         | 
| 37 | 
            -
                    @ | 
| 38 | 
            -
                    @ | 
| 39 | 
            -
                    @ | 
| 38 | 
            +
                    @shared_upserts = []
         | 
| 39 | 
            +
                    @shared_inserts = []
         | 
| 40 | 
            +
                    @shared_updates = []
         | 
| 41 | 
            +
                    @shared_deletes = []
         | 
| 40 42 | 
             
                  end
         | 
| 41 43 |  | 
| 42 44 | 
             
                  ##
         | 
| @@ -46,19 +48,56 @@ module Gcloud | |
| 46 48 | 
             
                  #
         | 
| 47 49 | 
             
                  # @example
         | 
| 48 50 | 
             
                  #   gcloud = Gcloud.new
         | 
| 49 | 
            -
                  #    | 
| 50 | 
            -
                  #    | 
| 51 | 
            +
                  #   datastore = gcloud.datastore
         | 
| 52 | 
            +
                  #   datastore.commit do |c|
         | 
| 51 53 | 
             
                  #     c.save task1, task2
         | 
| 52 54 | 
             
                  #   end
         | 
| 53 55 | 
             
                  #
         | 
| 54 56 | 
             
                  def save *entities
         | 
| 55 | 
            -
                    entities | 
| 56 | 
            -
             | 
| 57 | 
            -
                      shared_entities << entity
         | 
| 58 | 
            -
                    end
         | 
| 57 | 
            +
                    entities = Array(entities).flatten
         | 
| 58 | 
            +
                    @shared_upserts += entities unless entities.empty?
         | 
| 59 59 | 
             
                    # Do not save yet
         | 
| 60 60 | 
             
                    entities
         | 
| 61 61 | 
             
                  end
         | 
| 62 | 
            +
                  alias_method :upsert, :save
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  ##
         | 
| 65 | 
            +
                  # Inserts entities to the Datastore.
         | 
| 66 | 
            +
                  #
         | 
| 67 | 
            +
                  # @param [Entity] entities One or more Entity objects to insert.
         | 
| 68 | 
            +
                  #
         | 
| 69 | 
            +
                  # @example
         | 
| 70 | 
            +
                  #   gcloud = Gcloud.new
         | 
| 71 | 
            +
                  #   datastore = gcloud.datastore
         | 
| 72 | 
            +
                  #   datastore.commit do |c|
         | 
| 73 | 
            +
                  #     c.insert task1, task2
         | 
| 74 | 
            +
                  #   end
         | 
| 75 | 
            +
                  #
         | 
| 76 | 
            +
                  def insert *entities
         | 
| 77 | 
            +
                    entities = Array(entities).flatten
         | 
| 78 | 
            +
                    @shared_inserts += entities unless entities.empty?
         | 
| 79 | 
            +
                    # Do not insert yet
         | 
| 80 | 
            +
                    entities
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  ##
         | 
| 84 | 
            +
                  # Updates entities to the Datastore.
         | 
| 85 | 
            +
                  #
         | 
| 86 | 
            +
                  # @param [Entity] entities One or more Entity objects to update.
         | 
| 87 | 
            +
                  #
         | 
| 88 | 
            +
                  # @example
         | 
| 89 | 
            +
                  #   gcloud = Gcloud.new
         | 
| 90 | 
            +
                  #   datastore = gcloud.datastore
         | 
| 91 | 
            +
                  #   datastore.commit do |c|
         | 
| 92 | 
            +
                  #     c.update task1, task2
         | 
| 93 | 
            +
                  #   end
         | 
| 94 | 
            +
                  #
         | 
| 95 | 
            +
                  def update *entities
         | 
| 96 | 
            +
                    entities = Array(entities).flatten
         | 
| 97 | 
            +
                    @shared_updates += entities unless entities.empty?
         | 
| 98 | 
            +
                    # Do not update yet
         | 
| 99 | 
            +
                    entities
         | 
| 100 | 
            +
                  end
         | 
| 62 101 |  | 
| 63 102 | 
             
                  ##
         | 
| 64 103 | 
             
                  # Remove entities from the Datastore.
         | 
| @@ -68,63 +107,41 @@ module Gcloud | |
| 68 107 | 
             
                  #
         | 
| 69 108 | 
             
                  # @example
         | 
| 70 109 | 
             
                  #   gcloud = Gcloud.new
         | 
| 71 | 
            -
                  #    | 
| 72 | 
            -
                  #    | 
| 73 | 
            -
                  #     c.delete  | 
| 110 | 
            +
                  #   datastore = gcloud.datastore
         | 
| 111 | 
            +
                  #   datastore.commit do |c|
         | 
| 112 | 
            +
                  #     c.delete task1, task2
         | 
| 74 113 | 
             
                  #   end
         | 
| 75 114 | 
             
                  #
         | 
| 76 115 | 
             
                  def delete *entities_or_keys
         | 
| 77 | 
            -
                    keys = entities_or_keys.map do |e_or_k|
         | 
| 116 | 
            +
                    keys = Array(entities_or_keys).flatten.map do |e_or_k|
         | 
| 78 117 | 
             
                      e_or_k.respond_to?(:key) ? e_or_k.key : e_or_k
         | 
| 79 118 | 
             
                    end
         | 
| 80 | 
            -
                     | 
| 119 | 
            +
                    @shared_deletes += keys unless keys.empty?
         | 
| 81 120 | 
             
                    # Do not delete yet
         | 
| 82 121 | 
             
                    true
         | 
| 83 122 | 
             
                  end
         | 
| 84 123 |  | 
| 85 | 
            -
                  # @private  | 
| 86 | 
            -
                  def  | 
| 87 | 
            -
                     | 
| 88 | 
            -
             | 
| 89 | 
            -
                       | 
| 90 | 
            -
                      m.delete = shared_deletes.map(&:to_proto)
         | 
| 124 | 
            +
                  # @private Mutations object to be committed.
         | 
| 125 | 
            +
                  def mutations
         | 
| 126 | 
            +
                    mutations = []
         | 
| 127 | 
            +
                    mutations += @shared_upserts.map do |entity|
         | 
| 128 | 
            +
                      Google::Datastore::V1beta3::Mutation.new upsert: entity.to_grpc
         | 
| 91 129 | 
             
                    end
         | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 96 | 
            -
             | 
| 130 | 
            +
                    mutations += @shared_inserts.map do |entity|
         | 
| 131 | 
            +
                      Google::Datastore::V1beta3::Mutation.new insert: entity.to_grpc
         | 
| 132 | 
            +
                    end
         | 
| 133 | 
            +
                    mutations += @shared_updates.map do |entity|
         | 
| 134 | 
            +
                      Google::Datastore::V1beta3::Mutation.new update: entity.to_grpc
         | 
| 135 | 
            +
                    end
         | 
| 136 | 
            +
                    mutations += @shared_deletes.map do |key|
         | 
| 137 | 
            +
                      Google::Datastore::V1beta3::Mutation.new delete: key.to_grpc
         | 
| 138 | 
            +
                    end
         | 
| 139 | 
            +
                    mutations
         | 
| 97 140 | 
             
                  end
         | 
| 98 141 |  | 
| 99 142 | 
             
                  # @private All entities saved in the commit.
         | 
| 100 143 | 
             
                  def entities
         | 
| 101 | 
            -
                     | 
| 102 | 
            -
                  end
         | 
| 103 | 
            -
             | 
| 104 | 
            -
                  protected
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                  ##
         | 
| 107 | 
            -
                  # @private List of Entity objects to be saved.
         | 
| 108 | 
            -
                  def shared_entities
         | 
| 109 | 
            -
                    @shared_entities
         | 
| 110 | 
            -
                  end
         | 
| 111 | 
            -
             | 
| 112 | 
            -
                  ##
         | 
| 113 | 
            -
                  # @private List of Entity objects that need auto_ids
         | 
| 114 | 
            -
                  def shared_auto_ids
         | 
| 115 | 
            -
                    @shared_auto_ids
         | 
| 116 | 
            -
                  end
         | 
| 117 | 
            -
             | 
| 118 | 
            -
                  ##
         | 
| 119 | 
            -
                  # @private List of Entity objects to be saved.
         | 
| 120 | 
            -
                  def shared_upserts
         | 
| 121 | 
            -
                    shared_entities - shared_auto_ids
         | 
| 122 | 
            -
                  end
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                  ##
         | 
| 125 | 
            -
                  # @private List of Key objects to be deleted.
         | 
| 126 | 
            -
                  def shared_deletes
         | 
| 127 | 
            -
                    @shared_deletes
         | 
| 144 | 
            +
                    @shared_upserts + @shared_inserts + @shared_updates
         | 
| 128 145 | 
             
                  end
         | 
| 129 146 | 
             
                end
         | 
| 130 147 | 
             
              end
         | 
| @@ -26,21 +26,10 @@ module Gcloud | |
| 26 26 | 
             
                #
         | 
| 27 27 | 
             
                # @see https://developers.google.com/accounts/docs/application-default-credentials
         | 
| 28 28 | 
             
                class Credentials < Gcloud::Credentials
         | 
| 29 | 
            -
                  SCOPE = ["https://www.googleapis.com/auth/datastore" | 
| 30 | 
            -
                           "https://www.googleapis.com/auth/userinfo.email"]
         | 
| 29 | 
            +
                  SCOPE = ["https://www.googleapis.com/auth/datastore"]
         | 
| 31 30 | 
             
                  PATH_ENV_VARS = %w(DATASTORE_KEYFILE GCLOUD_KEYFILE GOOGLE_CLOUD_KEYFILE)
         | 
| 32 31 | 
             
                  JSON_ENV_VARS = %w(DATASTORE_KEYFILE_JSON GCLOUD_KEYFILE_JSON
         | 
| 33 32 | 
             
                                     GOOGLE_CLOUD_KEYFILE_JSON)
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                  ##
         | 
| 36 | 
            -
                  # Sign OAuth 2.0 API calls.
         | 
| 37 | 
            -
                  def sign_http_request request
         | 
| 38 | 
            -
                    if @client
         | 
| 39 | 
            -
                      @client.fetch_access_token! if @client.expires_within? 30
         | 
| 40 | 
            -
                      @client.generate_authenticated_request request: request
         | 
| 41 | 
            -
                    end
         | 
| 42 | 
            -
                    request
         | 
| 43 | 
            -
                  end
         | 
| 44 33 | 
             
                end
         | 
| 45 34 | 
             
              end
         | 
| 46 35 | 
             
            end
         | 
| @@ -0,0 +1,76 @@ | |
| 1 | 
            +
            # Copyright 2016 Google Inc. All rights reserved.
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 4 | 
            +
            # you may not use this file except in compliance with the License.
         | 
| 5 | 
            +
            # You may obtain a copy of the License at
         | 
| 6 | 
            +
            #
         | 
| 7 | 
            +
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 8 | 
            +
            #
         | 
| 9 | 
            +
            # Unless required by applicable law or agreed to in writing, software
         | 
| 10 | 
            +
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 11 | 
            +
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| 12 | 
            +
            # See the License for the specific language governing permissions and
         | 
| 13 | 
            +
            # limitations under the License.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
             | 
| 16 | 
            +
            module Gcloud
         | 
| 17 | 
            +
              module Datastore
         | 
| 18 | 
            +
                ##
         | 
| 19 | 
            +
                # # Cursor
         | 
| 20 | 
            +
                #
         | 
| 21 | 
            +
                # Cursor is a point in query results. Cursors are returned in QueryResults.
         | 
| 22 | 
            +
                #
         | 
| 23 | 
            +
                # @example
         | 
| 24 | 
            +
                #   require "gcloud"
         | 
| 25 | 
            +
                #
         | 
| 26 | 
            +
                #   gcloud = Gcloud.new
         | 
| 27 | 
            +
                #   datastore = gcloud.datastore
         | 
| 28 | 
            +
                #
         | 
| 29 | 
            +
                #   query = datastore.query("Task").
         | 
| 30 | 
            +
                #     where("done", "=", false)
         | 
| 31 | 
            +
                #
         | 
| 32 | 
            +
                #   tasks = datastore.run query
         | 
| 33 | 
            +
                #   tasks.cursor #=> Cursor
         | 
| 34 | 
            +
                #
         | 
| 35 | 
            +
                class Cursor
         | 
| 36 | 
            +
                  # Base64 encoded array of bytes
         | 
| 37 | 
            +
                  def initialize cursor
         | 
| 38 | 
            +
                    @cursor = cursor
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  # Base64 encoded array of bytes
         | 
| 42 | 
            +
                  def to_s
         | 
| 43 | 
            +
                    @cursor
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  # @private
         | 
| 47 | 
            +
                  def inspect
         | 
| 48 | 
            +
                    "#{self.class}(#{@cursor})"
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  # @private
         | 
| 52 | 
            +
                  def == other
         | 
| 53 | 
            +
                    return false unless other.is_a? Cursor
         | 
| 54 | 
            +
                    @cursor == other.to_s
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  # @private
         | 
| 58 | 
            +
                  def <=> other
         | 
| 59 | 
            +
                    return -1 unless other.is_a? Cursor
         | 
| 60 | 
            +
                    @cursor <=> other.to_s
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  # @private byte array as a string
         | 
| 64 | 
            +
                  def to_grpc
         | 
| 65 | 
            +
                    GRPCUtils.decode_bytes(@cursor)
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  # @private byte array as a string
         | 
| 69 | 
            +
                  def self.from_grpc grpc
         | 
| 70 | 
            +
                    grpc = String grpc
         | 
| 71 | 
            +
                    return nil if grpc.empty?
         | 
| 72 | 
            +
                    new GRPCUtils.encode_bytes(grpc)
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
            end
         | 
| @@ -14,12 +14,15 @@ | |
| 14 14 |  | 
| 15 15 |  | 
| 16 16 | 
             
            require "gcloud/gce"
         | 
| 17 | 
            -
            require "gcloud/datastore/ | 
| 17 | 
            +
            require "gcloud/datastore/grpc_utils"
         | 
| 18 18 | 
             
            require "gcloud/datastore/credentials"
         | 
| 19 | 
            +
            require "gcloud/datastore/service"
         | 
| 19 20 | 
             
            require "gcloud/datastore/commit"
         | 
| 20 21 | 
             
            require "gcloud/datastore/entity"
         | 
| 21 22 | 
             
            require "gcloud/datastore/key"
         | 
| 22 23 | 
             
            require "gcloud/datastore/query"
         | 
| 24 | 
            +
            require "gcloud/datastore/gql_query"
         | 
| 25 | 
            +
            require "gcloud/datastore/cursor"
         | 
| 23 26 | 
             
            require "gcloud/datastore/dataset/lookup_results"
         | 
| 24 27 | 
             
            require "gcloud/datastore/dataset/query_results"
         | 
| 25 28 |  | 
| @@ -41,16 +44,17 @@ module Gcloud | |
| 41 44 | 
             
                #   require "gcloud"
         | 
| 42 45 | 
             
                #
         | 
| 43 46 | 
             
                #   gcloud = Gcloud.new
         | 
| 44 | 
            -
                #    | 
| 47 | 
            +
                #   datastore = gcloud.datastore
         | 
| 45 48 | 
             
                #
         | 
| 46 | 
            -
                #   query =  | 
| 47 | 
            -
                #     where(" | 
| 49 | 
            +
                #   query = datastore.query("Task").
         | 
| 50 | 
            +
                #     where("done", "=", false)
         | 
| 48 51 | 
             
                #
         | 
| 49 | 
            -
                #   tasks =  | 
| 52 | 
            +
                #   tasks = datastore.run query
         | 
| 50 53 | 
             
                #
         | 
| 51 54 | 
             
                class Dataset
         | 
| 52 | 
            -
                   | 
| 53 | 
            -
                   | 
| 55 | 
            +
                  ##
         | 
| 56 | 
            +
                  # @private The gRPC Service object.
         | 
| 57 | 
            +
                  attr_accessor :service
         | 
| 54 58 |  | 
| 55 59 | 
             
                  ##
         | 
| 56 60 | 
             
                  # @private Creates a new Dataset instance.
         | 
| @@ -59,7 +63,7 @@ module Gcloud | |
| 59 63 | 
             
                  def initialize project, credentials
         | 
| 60 64 | 
             
                    project = project.to_s # Always cast to a string
         | 
| 61 65 | 
             
                    fail ArgumentError, "project is missing" if project.empty?
         | 
| 62 | 
            -
                    @ | 
| 66 | 
            +
                    @service = Service.new project, credentials
         | 
| 63 67 | 
             
                  end
         | 
| 64 68 |  | 
| 65 69 | 
             
                  ##
         | 
| @@ -71,11 +75,11 @@ module Gcloud | |
| 71 75 | 
             
                  #   gcloud = Gcloud.new "my-todo-project",
         | 
| 72 76 | 
             
                  #                       "/path/to/keyfile.json"
         | 
| 73 77 | 
             
                  #
         | 
| 74 | 
            -
                  #    | 
| 75 | 
            -
                  #    | 
| 78 | 
            +
                  #   datastore = gcloud.datastore
         | 
| 79 | 
            +
                  #   datastore.project #=> "my-todo-project"
         | 
| 76 80 | 
             
                  #
         | 
| 77 81 | 
             
                  def project
         | 
| 78 | 
            -
                     | 
| 82 | 
            +
                    service.project
         | 
| 79 83 | 
             
                  end
         | 
| 80 84 |  | 
| 81 85 | 
             
                  ##
         | 
| @@ -97,19 +101,20 @@ module Gcloud | |
| 97 101 | 
             
                  # @return [Array<Gcloud::Datastore::Key>]
         | 
| 98 102 | 
             
                  #
         | 
| 99 103 | 
             
                  # @example
         | 
| 100 | 
            -
                  #    | 
| 101 | 
            -
                  #   task_keys =  | 
| 104 | 
            +
                  #   task_key = datastore.key "Task"
         | 
| 105 | 
            +
                  #   task_keys = datastore.allocate_ids task_key, 5
         | 
| 102 106 | 
             
                  #
         | 
| 103 107 | 
             
                  def allocate_ids incomplete_key, count = 1
         | 
| 104 108 | 
             
                    if incomplete_key.complete?
         | 
| 105 109 | 
             
                      fail Gcloud::Datastore::Error, "An incomplete key must be provided."
         | 
| 106 110 | 
             
                    end
         | 
| 107 111 |  | 
| 108 | 
            -
                     | 
| 109 | 
            -
                     | 
| 110 | 
            -
                     | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 112 | 
            +
                    ensure_service!
         | 
| 113 | 
            +
                    incomplete_keys = count.times.map { incomplete_key.to_grpc }
         | 
| 114 | 
            +
                    allocate_res = service.allocate_ids(*incomplete_keys)
         | 
| 115 | 
            +
                    allocate_res.keys.map { |key| Key.from_grpc key }
         | 
| 116 | 
            +
                  rescue GRPC::BadStatus => e
         | 
| 117 | 
            +
                    raise Gcloud::Error.from_error(e)
         | 
| 113 118 | 
             
                  end
         | 
| 114 119 |  | 
| 115 120 | 
             
                  ##
         | 
| @@ -119,12 +124,106 @@ module Gcloud | |
| 119 124 | 
             
                  #
         | 
| 120 125 | 
             
                  # @return [Array<Gcloud::Datastore::Entity>]
         | 
| 121 126 | 
             
                  #
         | 
| 122 | 
            -
                  # @example
         | 
| 123 | 
            -
                  #    | 
| 127 | 
            +
                  # @example Insert a new entity:
         | 
| 128 | 
            +
                  #   task = datastore.entity "Task" do |t|
         | 
| 129 | 
            +
                  #     t["type"] = "Personal"
         | 
| 130 | 
            +
                  #     t["done"] = false
         | 
| 131 | 
            +
                  #     t["priority"] = 4
         | 
| 132 | 
            +
                  #     t["description"] = "Learn Cloud Datastore"
         | 
| 133 | 
            +
                  #   end
         | 
| 134 | 
            +
                  #   task.key.id #=> nil
         | 
| 135 | 
            +
                  #   datastore.save task
         | 
| 136 | 
            +
                  #   task.key.id #=> 123456
         | 
| 137 | 
            +
                  #
         | 
| 138 | 
            +
                  # @example Insert multiple new entities in a batch:
         | 
| 139 | 
            +
                  #   task1 = datastore.entity "Task" do |t|
         | 
| 140 | 
            +
                  #     t["type"] = "Personal"
         | 
| 141 | 
            +
                  #     t["done"] = false
         | 
| 142 | 
            +
                  #     t["priority"] = 4
         | 
| 143 | 
            +
                  #     t["description"] = "Learn Cloud Datastore"
         | 
| 144 | 
            +
                  #   end
         | 
| 145 | 
            +
                  #
         | 
| 146 | 
            +
                  #   task2 = datastore.entity "Task" do |t|
         | 
| 147 | 
            +
                  #     t["type"] = "Personal"
         | 
| 148 | 
            +
                  #     t["done"] = false
         | 
| 149 | 
            +
                  #     t["priority"] = 5
         | 
| 150 | 
            +
                  #     t["description"] = "Integrate Cloud Datastore"
         | 
| 151 | 
            +
                  #   end
         | 
| 152 | 
            +
                  #
         | 
| 153 | 
            +
                  #   task_key1, task_key2 = datastore.save(task1, task2).map(&:key)
         | 
| 154 | 
            +
                  #
         | 
| 155 | 
            +
                  # @example Update an existing entity:
         | 
| 156 | 
            +
                  #   task = datastore.find "Task", "sampleTask"
         | 
| 157 | 
            +
                  #   task["priority"] = 5
         | 
| 158 | 
            +
                  #   datastore.save task
         | 
| 124 159 | 
             
                  #
         | 
| 125 160 | 
             
                  def save *entities
         | 
| 126 161 | 
             
                    commit { |c| c.save(*entities) }
         | 
| 127 162 | 
             
                  end
         | 
| 163 | 
            +
                  alias_method :upsert, :save
         | 
| 164 | 
            +
             | 
| 165 | 
            +
                  ##
         | 
| 166 | 
            +
                  # Insert one or more entities to the Datastore. An InvalidArgumentError
         | 
| 167 | 
            +
                  # will raised if the entities cannot be inserted.
         | 
| 168 | 
            +
                  #
         | 
| 169 | 
            +
                  # @param [Entity] entities One or more entity objects to be inserted.
         | 
| 170 | 
            +
                  #
         | 
| 171 | 
            +
                  # @return [Array<Gcloud::Datastore::Entity>]
         | 
| 172 | 
            +
                  #
         | 
| 173 | 
            +
                  # @example Insert a new entity:
         | 
| 174 | 
            +
                  #   task = datastore.entity "Task" do |t|
         | 
| 175 | 
            +
                  #     t["type"] = "Personal"
         | 
| 176 | 
            +
                  #     t["done"] = false
         | 
| 177 | 
            +
                  #     t["priority"] = 4
         | 
| 178 | 
            +
                  #     t["description"] = "Learn Cloud Datastore"
         | 
| 179 | 
            +
                  #   end
         | 
| 180 | 
            +
                  #   task.key.id #=> nil
         | 
| 181 | 
            +
                  #   datastore.insert task
         | 
| 182 | 
            +
                  #   task.key.id #=> 123456
         | 
| 183 | 
            +
                  #
         | 
| 184 | 
            +
                  # @example Insert multiple new entities in a batch:
         | 
| 185 | 
            +
                  #   task1 = datastore.entity "Task" do |t|
         | 
| 186 | 
            +
                  #     t["type"] = "Personal"
         | 
| 187 | 
            +
                  #     t["done"] = false
         | 
| 188 | 
            +
                  #     t["priority"] = 4
         | 
| 189 | 
            +
                  #     t["description"] = "Learn Cloud Datastore"
         | 
| 190 | 
            +
                  #   end
         | 
| 191 | 
            +
                  #
         | 
| 192 | 
            +
                  #   task2 = datastore.entity "Task" do |t|
         | 
| 193 | 
            +
                  #     t["type"] = "Personal"
         | 
| 194 | 
            +
                  #     t["done"] = false
         | 
| 195 | 
            +
                  #     t["priority"] = 5
         | 
| 196 | 
            +
                  #     t["description"] = "Integrate Cloud Datastore"
         | 
| 197 | 
            +
                  #   end
         | 
| 198 | 
            +
                  #
         | 
| 199 | 
            +
                  #   task_key1, task_key2 = datastore.insert(task1, task2).map(&:key)
         | 
| 200 | 
            +
                  #
         | 
| 201 | 
            +
                  def insert *entities
         | 
| 202 | 
            +
                    commit { |c| c.insert(*entities) }
         | 
| 203 | 
            +
                  end
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                  ##
         | 
| 206 | 
            +
                  # Update one or more entities to the Datastore. An InvalidArgumentError
         | 
| 207 | 
            +
                  # will raised if the entities cannot be updated.
         | 
| 208 | 
            +
                  #
         | 
| 209 | 
            +
                  # @param [Entity] entities One or more entity objects to be updated.
         | 
| 210 | 
            +
                  #
         | 
| 211 | 
            +
                  # @return [Array<Gcloud::Datastore::Entity>]
         | 
| 212 | 
            +
                  #
         | 
| 213 | 
            +
                  # @example Update an existing entity:
         | 
| 214 | 
            +
                  #   task = datastore.find "Task", "sampleTask"
         | 
| 215 | 
            +
                  #   task["done"] = true
         | 
| 216 | 
            +
                  #   datastore.save task
         | 
| 217 | 
            +
                  #
         | 
| 218 | 
            +
                  # @example update multiple new entities in a batch:
         | 
| 219 | 
            +
                  #   query = datastore.query("Task").where("done", "=", false)
         | 
| 220 | 
            +
                  #   tasks = datastore.run query
         | 
| 221 | 
            +
                  #   tasks.each { |t| t["done"] = true }
         | 
| 222 | 
            +
                  #   datastore.update tasks
         | 
| 223 | 
            +
                  #
         | 
| 224 | 
            +
                  def update *entities
         | 
| 225 | 
            +
                    commit { |c| c.update(*entities) }
         | 
| 226 | 
            +
                  end
         | 
| 128 227 |  | 
| 129 228 | 
             
                  ##
         | 
| 130 229 | 
             
                  # Remove entities from the Datastore.
         | 
| @@ -136,8 +235,8 @@ module Gcloud | |
| 136 235 | 
             
                  #
         | 
| 137 236 | 
             
                  # @example
         | 
| 138 237 | 
             
                  #   gcloud = Gcloud.new
         | 
| 139 | 
            -
                  #    | 
| 140 | 
            -
                  #    | 
| 238 | 
            +
                  #   datastore = gcloud.datastore
         | 
| 239 | 
            +
                  #   datastore.delete task1, task2
         | 
| 141 240 | 
             
                  #
         | 
| 142 241 | 
             
                  def delete *entities_or_keys
         | 
| 143 242 | 
             
                    commit { |c| c.delete(*entities_or_keys) }
         | 
| @@ -154,26 +253,34 @@ module Gcloud | |
| 154 253 | 
             
                  #   persisted.
         | 
| 155 254 | 
             
                  #
         | 
| 156 255 | 
             
                  # @example
         | 
| 157 | 
            -
                  #    | 
| 158 | 
            -
                  # | 
| 159 | 
            -
                  # | 
| 256 | 
            +
                  #   gcloud = Gcloud.new
         | 
| 257 | 
            +
                  #   datastore = gcloud.datastore
         | 
| 258 | 
            +
                  #   datastore.commit do |c|
         | 
| 259 | 
            +
                  #     c.save task3, task4
         | 
| 260 | 
            +
                  #     c.delete task1, task2
         | 
| 160 261 | 
             
                  #   end
         | 
| 161 262 | 
             
                  #
         | 
| 162 263 | 
             
                  def commit
         | 
| 163 264 | 
             
                    return unless block_given?
         | 
| 164 265 | 
             
                    c = Commit.new
         | 
| 165 266 | 
             
                    yield c
         | 
| 166 | 
            -
             | 
| 167 | 
            -
                     | 
| 168 | 
            -
             | 
| 169 | 
            -
                    # Make sure all entity keys are frozen so all show as persisted
         | 
| 267 | 
            +
             | 
| 268 | 
            +
                    ensure_service!
         | 
| 269 | 
            +
                    commit_res = service.commit c.mutations
         | 
| 170 270 | 
             
                    entities = c.entities
         | 
| 271 | 
            +
                    returned_keys = commit_res.mutation_results.map(&:key)
         | 
| 272 | 
            +
                    returned_keys.each_with_index do |key, index|
         | 
| 273 | 
            +
                      next if entities[index].nil?
         | 
| 274 | 
            +
                      entities[index].key = Key.from_grpc(key) unless key.nil?
         | 
| 275 | 
            +
                    end
         | 
| 171 276 | 
             
                    entities.each { |e| e.key.freeze unless e.persisted? }
         | 
| 172 277 | 
             
                    entities
         | 
| 278 | 
            +
                  rescue GRPC::BadStatus => e
         | 
| 279 | 
            +
                    raise Gcloud::Error.from_error(e)
         | 
| 173 280 | 
             
                  end
         | 
| 174 281 |  | 
| 175 282 | 
             
                  ##
         | 
| 176 | 
            -
                  # Retrieve an entity by  | 
| 283 | 
            +
                  # Retrieve an entity by key.
         | 
| 177 284 | 
             
                  #
         | 
| 178 285 | 
             
                  # @param [Key, String] key_or_kind A Key object or `kind` string value.
         | 
| 179 286 | 
             
                  # @param [Integer, String, nil] id_or_name The Key's `id` or `name` value
         | 
| @@ -190,11 +297,11 @@ module Gcloud | |
| 190 297 | 
             
                  # @return [Gcloud::Datastore::Entity, nil]
         | 
| 191 298 | 
             
                  #
         | 
| 192 299 | 
             
                  # @example Finding an entity with a key:
         | 
| 193 | 
            -
                  #    | 
| 194 | 
            -
                  #   task =  | 
| 300 | 
            +
                  #   task_key = datastore.key "Task", "sampleTask"
         | 
| 301 | 
            +
                  #   task = datastore.find task_key
         | 
| 195 302 | 
             
                  #
         | 
| 196 303 | 
             
                  # @example Finding an entity with a `kind` and `id`/`name`:
         | 
| 197 | 
            -
                  #   task =  | 
| 304 | 
            +
                  #   task = datastore.find "Task", "sampleTask"
         | 
| 198 305 | 
             
                  #
         | 
| 199 306 | 
             
                  def find key_or_kind, id_or_name = nil, consistency: nil
         | 
| 200 307 | 
             
                    key = key_or_kind
         | 
| @@ -206,7 +313,8 @@ module Gcloud | |
| 206 313 | 
             
                  alias_method :get, :find
         | 
| 207 314 |  | 
| 208 315 | 
             
                  ##
         | 
| 209 | 
            -
                  # Retrieve the entities for the provided keys.
         | 
| 316 | 
            +
                  # Retrieve the entities for the provided keys. The order of results is
         | 
| 317 | 
            +
                  # undefined and has no relation to the order of `keys` arguments.
         | 
| 210 318 | 
             
                  #
         | 
| 211 319 | 
             
                  # @param [Key] keys One or more Key objects to find records for.
         | 
| 212 320 | 
             
                  # @param [Symbol] consistency The non-transactional read consistency to
         | 
| @@ -222,26 +330,30 @@ module Gcloud | |
| 222 330 | 
             
                  #
         | 
| 223 331 | 
             
                  # @example
         | 
| 224 332 | 
             
                  #   gcloud = Gcloud.new
         | 
| 225 | 
            -
                  #    | 
| 226 | 
            -
                  # | 
| 227 | 
            -
                  #    | 
| 228 | 
            -
                  #    | 
| 333 | 
            +
                  #   datastore = gcloud.datastore
         | 
| 334 | 
            +
                  #
         | 
| 335 | 
            +
                  #   task_key1 = datastore.key "Task", "sampleTask1"
         | 
| 336 | 
            +
                  #   task_key2 = datastore.key "Task", "sampleTask2"
         | 
| 337 | 
            +
                  #   tasks = datastore.find_all task_key1, task_key2
         | 
| 229 338 | 
             
                  #
         | 
| 230 339 | 
             
                  def find_all *keys, consistency: nil
         | 
| 340 | 
            +
                    ensure_service!
         | 
| 231 341 | 
             
                    check_consistency! consistency
         | 
| 232 | 
            -
                     | 
| 233 | 
            -
             | 
| 234 | 
            -
                    entities = to_gcloud_entities  | 
| 235 | 
            -
                    deferred = to_gcloud_keys  | 
| 236 | 
            -
                    missing  = to_gcloud_entities  | 
| 342 | 
            +
                    lookup_res = service.lookup(*keys.map(&:to_grpc),
         | 
| 343 | 
            +
                                                consistency: consistency)
         | 
| 344 | 
            +
                    entities = to_gcloud_entities lookup_res.found
         | 
| 345 | 
            +
                    deferred = to_gcloud_keys lookup_res.deferred
         | 
| 346 | 
            +
                    missing  = to_gcloud_entities lookup_res.missing
         | 
| 237 347 | 
             
                    LookupResults.new entities, deferred, missing
         | 
| 348 | 
            +
                  rescue GRPC::BadStatus => e
         | 
| 349 | 
            +
                    raise Gcloud::Error.from_error(e)
         | 
| 238 350 | 
             
                  end
         | 
| 239 351 | 
             
                  alias_method :lookup, :find_all
         | 
| 240 352 |  | 
| 241 353 | 
             
                  ##
         | 
| 242 354 | 
             
                  # Retrieve entities specified by a Query.
         | 
| 243 355 | 
             
                  #
         | 
| 244 | 
            -
                  # @param [Query] query The  | 
| 356 | 
            +
                  # @param [Query, GqlQuery] query The object with the search criteria.
         | 
| 245 357 | 
             
                  # @param [String] namespace The namespace the query is to run within.
         | 
| 246 358 | 
             
                  # @param [Symbol] consistency The non-transactional read consistency to
         | 
| 247 359 | 
             
                  #   use. Cannot be set to `:strong` for global queries. Accepted values
         | 
| @@ -255,24 +367,43 @@ module Gcloud | |
| 255 367 | 
             
                  # @return [Gcloud::Datastore::Dataset::QueryResults]
         | 
| 256 368 | 
             
                  #
         | 
| 257 369 | 
             
                  # @example
         | 
| 258 | 
            -
                  #   query =  | 
| 259 | 
            -
                  #     where(" | 
| 260 | 
            -
                  #   tasks =  | 
| 370 | 
            +
                  #   query = datastore.query("Task").
         | 
| 371 | 
            +
                  #     where("done", "=", false)
         | 
| 372 | 
            +
                  #   tasks = datastore.run query
         | 
| 373 | 
            +
                  #
         | 
| 374 | 
            +
                  # @example Run an ancestor query with eventual consistency:
         | 
| 375 | 
            +
                  #   task_list_key = datastore.key "TaskList", "default"
         | 
| 376 | 
            +
                  #   query.kind("Task").
         | 
| 377 | 
            +
                  #     ancestor(task_list_key)
         | 
| 378 | 
            +
                  #
         | 
| 379 | 
            +
                  #   tasks = datastore.run query, consistency: :eventual
         | 
| 261 380 | 
             
                  #
         | 
| 262 381 | 
             
                  # @example Run the query within a namespace with the `namespace` option:
         | 
| 263 | 
            -
                  #   query =  | 
| 264 | 
            -
                  #     where(" | 
| 265 | 
            -
                  #   tasks =  | 
| 382 | 
            +
                  #   query = datastore.query("Task").
         | 
| 383 | 
            +
                  #     where("done", "=", false)
         | 
| 384 | 
            +
                  #   tasks = datastore.run query, namespace: "ns~todo-project"
         | 
| 385 | 
            +
                  #
         | 
| 386 | 
            +
                  # @example Run the query with a GQL string.
         | 
| 387 | 
            +
                  #   gql_query = datastore.gql "SELECT * FROM Task WHERE done = @done",
         | 
| 388 | 
            +
                  #                             done: false
         | 
| 389 | 
            +
                  #   tasks = datastore.run gql_query
         | 
| 390 | 
            +
                  #
         | 
| 391 | 
            +
                  # @example Run the GQL query within a namespace with `namespace` option:
         | 
| 392 | 
            +
                  #   gql_query = datastore.gql "SELECT * FROM Task WHERE done = @done",
         | 
| 393 | 
            +
                  #                             done: false
         | 
| 394 | 
            +
                  #   tasks = datastore.run gql_query, namespace: "ns~todo-project"
         | 
| 266 395 | 
             
                  #
         | 
| 267 396 | 
             
                  def run query, namespace: nil, consistency: nil
         | 
| 268 | 
            -
                     | 
| 397 | 
            +
                    ensure_service!
         | 
| 398 | 
            +
                    unless query.is_a?(Query) || query.is_a?(GqlQuery)
         | 
| 399 | 
            +
                      fail ArgumentError, "Cannot run a #{query.class} object."
         | 
| 400 | 
            +
                    end
         | 
| 269 401 | 
             
                    check_consistency! consistency
         | 
| 270 | 
            -
                     | 
| 271 | 
            -
             | 
| 272 | 
            -
                     | 
| 273 | 
            -
             | 
| 274 | 
            -
                     | 
| 275 | 
            -
                    QueryResults.new entities, cursor, more_results
         | 
| 402 | 
            +
                    query_res = service.run_query query.to_grpc, namespace,
         | 
| 403 | 
            +
                                                  consistency: consistency
         | 
| 404 | 
            +
                    QueryResults.from_grpc query_res, service, namespace, query.to_grpc.dup
         | 
| 405 | 
            +
                  rescue GRPC::BadStatus => e
         | 
| 406 | 
            +
                    raise Gcloud::Error.from_error(e)
         | 
| 276 407 | 
             
                  end
         | 
| 277 408 | 
             
                  alias_method :run_query, :run
         | 
| 278 409 |  | 
| @@ -286,16 +417,18 @@ module Gcloud | |
| 286 417 | 
             
                  #   require "gcloud"
         | 
| 287 418 | 
             
                  #
         | 
| 288 419 | 
             
                  #   gcloud = Gcloud.new
         | 
| 289 | 
            -
                  #    | 
| 420 | 
            +
                  #   datastore = gcloud.datastore
         | 
| 290 421 | 
             
                  #
         | 
| 291 | 
            -
                  #    | 
| 292 | 
            -
                  #      | 
| 293 | 
            -
                  #      | 
| 422 | 
            +
                  #   task = datastore.entity "Task", "sampleTask" do |t|
         | 
| 423 | 
            +
                  #     t["type"] = "Personal"
         | 
| 424 | 
            +
                  #     t["done"] = false
         | 
| 425 | 
            +
                  #     t["priority"] = 4
         | 
| 426 | 
            +
                  #     t["description"] = "Learn Cloud Datastore"
         | 
| 294 427 | 
             
                  #   end
         | 
| 295 428 | 
             
                  #
         | 
| 296 | 
            -
                  #    | 
| 297 | 
            -
                  #     if tx.find( | 
| 298 | 
            -
                  #       tx.save  | 
| 429 | 
            +
                  #   datastore.transaction do |tx|
         | 
| 430 | 
            +
                  #     if tx.find(task.key).nil?
         | 
| 431 | 
            +
                  #       tx.save task
         | 
| 299 432 | 
             
                  #     end
         | 
| 300 433 | 
             
                  #   end
         | 
| 301 434 | 
             
                  #
         | 
| @@ -303,17 +436,19 @@ module Gcloud | |
| 303 436 | 
             
                  #   require "gcloud"
         | 
| 304 437 | 
             
                  #
         | 
| 305 438 | 
             
                  #   gcloud = Gcloud.new
         | 
| 306 | 
            -
                  #    | 
| 439 | 
            +
                  #   datastore = gcloud.datastore
         | 
| 307 440 | 
             
                  #
         | 
| 308 | 
            -
                  #    | 
| 309 | 
            -
                  #      | 
| 310 | 
            -
                  #      | 
| 441 | 
            +
                  #   task = datastore.entity "Task", "sampleTask" do |t|
         | 
| 442 | 
            +
                  #     t["type"] = "Personal"
         | 
| 443 | 
            +
                  #     t["done"] = false
         | 
| 444 | 
            +
                  #     t["priority"] = 4
         | 
| 445 | 
            +
                  #     t["description"] = "Learn Cloud Datastore"
         | 
| 311 446 | 
             
                  #   end
         | 
| 312 447 | 
             
                  #
         | 
| 313 | 
            -
                  #   tx =  | 
| 448 | 
            +
                  #   tx = datastore.transaction
         | 
| 314 449 | 
             
                  #   begin
         | 
| 315 | 
            -
                  #     if tx.find( | 
| 316 | 
            -
                  #       tx.save  | 
| 450 | 
            +
                  #     if tx.find(task.key).nil?
         | 
| 451 | 
            +
                  #       tx.save task
         | 
| 317 452 | 
             
                  #     end
         | 
| 318 453 | 
             
                  #     tx.commit
         | 
| 319 454 | 
             
                  #   rescue
         | 
| @@ -321,7 +456,7 @@ module Gcloud | |
| 321 456 | 
             
                  #   end
         | 
| 322 457 | 
             
                  #
         | 
| 323 458 | 
             
                  def transaction
         | 
| 324 | 
            -
                    tx = Transaction.new  | 
| 459 | 
            +
                    tx = Transaction.new service
         | 
| 325 460 | 
             
                    return tx unless block_given?
         | 
| 326 461 |  | 
| 327 462 | 
             
                    begin
         | 
| @@ -348,15 +483,15 @@ module Gcloud | |
| 348 483 | 
             
                  # @return [Gcloud::Datastore::Query]
         | 
| 349 484 | 
             
                  #
         | 
| 350 485 | 
             
                  # @example
         | 
| 351 | 
            -
                  #   query =  | 
| 352 | 
            -
                  #     where(" | 
| 353 | 
            -
                  #   tasks =  | 
| 486 | 
            +
                  #   query = datastore.query("Task").
         | 
| 487 | 
            +
                  #     where("done", "=", false)
         | 
| 488 | 
            +
                  #   tasks = datastore.run query
         | 
| 354 489 | 
             
                  #
         | 
| 355 490 | 
             
                  # @example The previous example is equivalent to:
         | 
| 356 491 | 
             
                  #   query = Gcloud::Datastore::Query.new.
         | 
| 357 492 | 
             
                  #     kind("Task").
         | 
| 358 | 
            -
                  #     where(" | 
| 359 | 
            -
                  #   tasks =  | 
| 493 | 
            +
                  #     where("done", "=", false)
         | 
| 494 | 
            +
                  #   tasks = datastore.run query
         | 
| 360 495 | 
             
                  #
         | 
| 361 496 | 
             
                  def query *kinds
         | 
| 362 497 | 
             
                    query = Query.new
         | 
| @@ -364,77 +499,155 @@ module Gcloud | |
| 364 499 | 
             
                    query
         | 
| 365 500 | 
             
                  end
         | 
| 366 501 |  | 
| 502 | 
            +
                  ##
         | 
| 503 | 
            +
                  # Create a new GqlQuery instance. This is a convenience method to make the
         | 
| 504 | 
            +
                  # creation of GqlQuery objects easier.
         | 
| 505 | 
            +
                  #
         | 
| 506 | 
            +
                  # @param [String] query The GQL query string.
         | 
| 507 | 
            +
                  # @param [Hash] bindings Named bindings for the GQL query string, each
         | 
| 508 | 
            +
                  #   key must match regex `[A-Za-z_$][A-Za-z_$0-9]*`, must not match regex
         | 
| 509 | 
            +
                  #   `__.*__`, and must not be `""`. The value must be an `Object` that can
         | 
| 510 | 
            +
                  #   be stored as an Entity property value, or a `Cursor`.
         | 
| 511 | 
            +
                  #
         | 
| 512 | 
            +
                  # @return [Gcloud::Datastore::GqlQuery]
         | 
| 513 | 
            +
                  #
         | 
| 514 | 
            +
                  # @example
         | 
| 515 | 
            +
                  #   gql_query = datastore.gql "SELECT * FROM Task WHERE done = @done",
         | 
| 516 | 
            +
                  #                             done: false
         | 
| 517 | 
            +
                  #   tasks = datastore.run gql_query
         | 
| 518 | 
            +
                  #
         | 
| 519 | 
            +
                  # @example The previous example is equivalent to:
         | 
| 520 | 
            +
                  #   gql_query = Gcloud::Datastore::GqlQuery.new
         | 
| 521 | 
            +
                  #   gql_query.query_string = "SELECT * FROM Task WHERE done = @done"
         | 
| 522 | 
            +
                  #   gql_query.named_bindings = {done: false}
         | 
| 523 | 
            +
                  #   tasks = datastore.run gql_query
         | 
| 524 | 
            +
                  #
         | 
| 525 | 
            +
                  def gql query, bindings = {}
         | 
| 526 | 
            +
                    gql = GqlQuery.new
         | 
| 527 | 
            +
                    gql.query_string = query
         | 
| 528 | 
            +
                    gql.named_bindings = bindings unless bindings.empty?
         | 
| 529 | 
            +
                    gql
         | 
| 530 | 
            +
                  end
         | 
| 531 | 
            +
             | 
| 367 532 | 
             
                  ##
         | 
| 368 533 | 
             
                  # Create a new Key instance. This is a convenience method to make the
         | 
| 369 534 | 
             
                  # creation of Key objects easier.
         | 
| 370 535 | 
             
                  #
         | 
| 371 | 
            -
                  # @param [String]  | 
| 372 | 
            -
                  #  | 
| 373 | 
            -
                  #   optional.
         | 
| 536 | 
            +
                  # @param [Array<Array(String,(String|Integer|nil))>] path An optional list
         | 
| 537 | 
            +
                  #   of pairs for the key's path. Each pair may include the key's kind
         | 
| 538 | 
            +
                  #   (String) and an id (Integer) or name (String). This is optional.
         | 
| 539 | 
            +
                  # @param [String] project The project of the Key. This is optional.
         | 
| 540 | 
            +
                  # @param [String] namespace namespace kind of the Key. This is optional.
         | 
| 374 541 | 
             
                  #
         | 
| 375 542 | 
             
                  # @return [Gcloud::Datastore::Key]
         | 
| 376 543 | 
             
                  #
         | 
| 377 544 | 
             
                  # @example
         | 
| 378 | 
            -
                  #    | 
| 545 | 
            +
                  #   task_key = datastore.key "Task", "sampleTask"
         | 
| 379 546 | 
             
                  #
         | 
| 380 547 | 
             
                  # @example The previous example is equivalent to:
         | 
| 381 | 
            -
                  #    | 
| 382 | 
            -
                  #
         | 
| 383 | 
            -
                   | 
| 384 | 
            -
             | 
| 548 | 
            +
                  #   task_key = Gcloud::Datastore::Key.new "Task", "sampleTask"
         | 
| 549 | 
            +
                  #
         | 
| 550 | 
            +
                  # @example Create an empty key:
         | 
| 551 | 
            +
                  #   key = datastore.key
         | 
| 552 | 
            +
                  #
         | 
| 553 | 
            +
                  # @example Create an incomplete key:
         | 
| 554 | 
            +
                  #   key = datastore.key "User"
         | 
| 555 | 
            +
                  #
         | 
| 556 | 
            +
                  # @example Create a key with a parent:
         | 
| 557 | 
            +
                  #   key = datastore.key [["TaskList", "default"], ["Task", "sampleTask"]]
         | 
| 558 | 
            +
                  #   key.path #=> [["TaskList", "default"], ["Task", "sampleTask"]]
         | 
| 559 | 
            +
                  #
         | 
| 560 | 
            +
                  # @example Create a key with multi-level ancestry:
         | 
| 561 | 
            +
                  #   key = datastore.key([
         | 
| 562 | 
            +
                  #     ["User", "alice"],
         | 
| 563 | 
            +
                  #     ["TaskList", "default"],
         | 
| 564 | 
            +
                  #     ["Task", "sampleTask"]
         | 
| 565 | 
            +
                  #   ])
         | 
| 566 | 
            +
                  #   key.path #=> [["User", "alice"], ["TaskList", "default"], [ ... ]]
         | 
| 567 | 
            +
                  #
         | 
| 568 | 
            +
                  # @example Create an incomplete key with a parent:
         | 
| 569 | 
            +
                  #   key = datastore.key "TaskList", "default", "Task"
         | 
| 570 | 
            +
                  #   key.path #=> [["TaskList", "default"], ["Task", nil]]
         | 
| 571 | 
            +
                  #
         | 
| 572 | 
            +
                  # @example Create a key with a project and namespace:
         | 
| 573 | 
            +
                  #   key = datastore.key ["TaskList", "default"], ["Task", "sampleTask"],
         | 
| 574 | 
            +
                  #                       project: "my-todo-project",
         | 
| 575 | 
            +
                  #                       namespace: "ns~todo-project"
         | 
| 576 | 
            +
                  #   key.path #=> [["TaskList", "default"], ["Task", "sampleTask"]]
         | 
| 577 | 
            +
                  #   key.project #=> "my-todo-project",
         | 
| 578 | 
            +
                  #   key.namespace #=> "ns~todo-project"
         | 
| 579 | 
            +
                  #
         | 
| 580 | 
            +
                  def key *path, project: nil, namespace: nil
         | 
| 581 | 
            +
                    path = path.flatten.each_slice(2).to_a # group in pairs
         | 
| 582 | 
            +
                    kind, id_or_name = path.pop
         | 
| 583 | 
            +
                    Key.new(kind, id_or_name).tap do |k|
         | 
| 584 | 
            +
                      k.project = project
         | 
| 585 | 
            +
                      k.namespace = namespace
         | 
| 586 | 
            +
                      unless path.empty?
         | 
| 587 | 
            +
                        k.parent = key path, project: project, namespace: namespace
         | 
| 588 | 
            +
                      end
         | 
| 589 | 
            +
                    end
         | 
| 385 590 | 
             
                  end
         | 
| 386 591 |  | 
| 387 592 | 
             
                  ##
         | 
| 388 593 | 
             
                  # Create a new empty Entity instance. This is a convenience method to make
         | 
| 389 594 | 
             
                  # the creation of Entity objects easier.
         | 
| 390 595 | 
             
                  #
         | 
| 391 | 
            -
                  # @param [Key, String, | 
| 392 | 
            -
                  #    | 
| 393 | 
            -
                  #  | 
| 394 | 
            -
                  #    | 
| 596 | 
            +
                  # @param [Key, Array<Array(String,(String|Integer|nil))>] key_or_path An
         | 
| 597 | 
            +
                  #   optional list of pairs for the key's path. Each pair may include the #
         | 
| 598 | 
            +
                  #   key's kind (String) and an id (Integer) or name (String). This is #
         | 
| 599 | 
            +
                  #   optional.
         | 
| 600 | 
            +
                  # @param [String] project The project of the Key. This is optional.
         | 
| 601 | 
            +
                  # @param [String] namespace namespace kind of the Key. This is optional.
         | 
| 395 602 | 
             
                  # @yield [entity] a block yielding a new entity
         | 
| 396 603 | 
             
                  # @yieldparam [Entity] entity the newly created entity object
         | 
| 397 604 | 
             
                  #
         | 
| 398 605 | 
             
                  # @return [Gcloud::Datastore::Entity]
         | 
| 399 606 | 
             
                  #
         | 
| 400 607 | 
             
                  # @example
         | 
| 401 | 
            -
                  #    | 
| 608 | 
            +
                  #   task = datastore.entity
         | 
| 402 609 | 
             
                  #
         | 
| 403 610 | 
             
                  # @example The previous example is equivalent to:
         | 
| 404 | 
            -
                  #    | 
| 611 | 
            +
                  #   task = Gcloud::Datastore::Entity.new
         | 
| 405 612 | 
             
                  #
         | 
| 406 613 | 
             
                  # @example The key can also be passed in as an object:
         | 
| 407 | 
            -
                  #    | 
| 408 | 
            -
                  #    | 
| 614 | 
            +
                  #   task_key = datastore.key "Task", "sampleTask"
         | 
| 615 | 
            +
                  #   task = datastore.entity task_key
         | 
| 409 616 | 
             
                  #
         | 
| 410 617 | 
             
                  # @example Or the key values can be passed in as parameters:
         | 
| 411 | 
            -
                  #    | 
| 618 | 
            +
                  #   task = datastore.entity "Task", "sampleTask"
         | 
| 412 619 | 
             
                  #
         | 
| 413 620 | 
             
                  # @example The previous example is equivalent to:
         | 
| 414 | 
            -
                  #    | 
| 415 | 
            -
                  #    | 
| 416 | 
            -
                  #    | 
| 621 | 
            +
                  #   task_key = Gcloud::Datastore::Key.new "Task", "sampleTask"
         | 
| 622 | 
            +
                  #   task = Gcloud::Datastore::Entity.new
         | 
| 623 | 
            +
                  #   task.key = task_key
         | 
| 417 624 | 
             
                  #
         | 
| 418 625 | 
             
                  # @example The newly created entity can also be configured using a block:
         | 
| 419 | 
            -
                  #    | 
| 420 | 
            -
                  #      | 
| 421 | 
            -
                  # | 
| 626 | 
            +
                  #   task = datastore.entity "Task", "sampleTask" do |t|
         | 
| 627 | 
            +
                  #     t["type"] = "Personal"
         | 
| 628 | 
            +
                  #     t["done"] = false
         | 
| 629 | 
            +
                  #     t["priority"] = 4
         | 
| 630 | 
            +
                  #     t["description"] = "Learn Cloud Datastore"
         | 
| 631 | 
            +
                  #   end
         | 
| 422 632 | 
             
                  #
         | 
| 423 633 | 
             
                  # @example The previous example is equivalent to:
         | 
| 424 | 
            -
                  #    | 
| 425 | 
            -
                  #    | 
| 426 | 
            -
                  #    | 
| 427 | 
            -
                  #    | 
| 428 | 
            -
                  #
         | 
| 429 | 
            -
                   | 
| 634 | 
            +
                  #   task_key = Gcloud::Datastore::Key.new "Task", "sampleTask"
         | 
| 635 | 
            +
                  #   task = Gcloud::Datastore::Entity.new
         | 
| 636 | 
            +
                  #   task.key = task_key
         | 
| 637 | 
            +
                  #   task["type"] = "Personal"
         | 
| 638 | 
            +
                  #   task["done"] = false
         | 
| 639 | 
            +
                  #   task["priority"] = 4
         | 
| 640 | 
            +
                  #   task["description"] = "Learn Cloud Datastore"
         | 
| 641 | 
            +
                  #
         | 
| 642 | 
            +
                  def entity *key_or_path, project: nil, namespace: nil
         | 
| 430 643 | 
             
                    entity = Entity.new
         | 
| 431 644 |  | 
| 432 645 | 
             
                    # Set the key
         | 
| 433 | 
            -
                     | 
| 434 | 
            -
             | 
| 435 | 
            -
             | 
| 646 | 
            +
                    if key_or_path.flatten.first.is_a? Gcloud::Datastore::Key
         | 
| 647 | 
            +
                      entity.key = key_or_path.flatten.first
         | 
| 648 | 
            +
                    else
         | 
| 649 | 
            +
                      entity.key = key key_or_path, project: project, namespace: namespace
         | 
| 436 650 | 
             
                    end
         | 
| 437 | 
            -
                    entity.key = key
         | 
| 438 651 |  | 
| 439 652 | 
             
                    yield entity if block_given?
         | 
| 440 653 |  | 
| @@ -444,37 +657,27 @@ module Gcloud | |
| 444 657 | 
             
                  protected
         | 
| 445 658 |  | 
| 446 659 | 
             
                  ##
         | 
| 447 | 
            -
                  #  | 
| 448 | 
            -
                   | 
| 449 | 
            -
             | 
| 450 | 
            -
                     | 
| 451 | 
            -
                      Entity.from_proto result.entity
         | 
| 452 | 
            -
                    end
         | 
| 660 | 
            +
                  # @private Raise an error unless an active connection to the service is
         | 
| 661 | 
            +
                  # available.
         | 
| 662 | 
            +
                  def ensure_service!
         | 
| 663 | 
            +
                    fail "Must have active connection to service" unless service
         | 
| 453 664 | 
             
                  end
         | 
| 454 665 |  | 
| 455 666 | 
             
                  ##
         | 
| 456 | 
            -
                  #  | 
| 457 | 
            -
                  def  | 
| 458 | 
            -
                    #  | 
| 459 | 
            -
                    Array( | 
| 460 | 
            -
                       | 
| 667 | 
            +
                  # Convenience method to convert GRPC entities to Gcloud entities.
         | 
| 668 | 
            +
                  def to_gcloud_entities grpc_entity_results
         | 
| 669 | 
            +
                    # Entities are nested in an object.
         | 
| 670 | 
            +
                    Array(grpc_entity_results).map do |result|
         | 
| 671 | 
            +
                      # TODO: Make this return an EntityResult with cursor...
         | 
| 672 | 
            +
                      Entity.from_grpc result.entity
         | 
| 461 673 | 
             
                    end
         | 
| 462 674 | 
             
                  end
         | 
| 463 675 |  | 
| 464 676 | 
             
                  ##
         | 
| 465 | 
            -
                  #  | 
| 466 | 
            -
                  def  | 
| 467 | 
            -
                     | 
| 468 | 
            -
             | 
| 469 | 
            -
                      entity.key = Key.from_proto key
         | 
| 470 | 
            -
                    end
         | 
| 471 | 
            -
                  end
         | 
| 472 | 
            -
             | 
| 473 | 
            -
                  def optional_partition_id namespace = nil
         | 
| 474 | 
            -
                    return nil if namespace.nil?
         | 
| 475 | 
            -
                    Proto::PartitionId.new.tap do |p|
         | 
| 476 | 
            -
                      p.namespace = namespace
         | 
| 477 | 
            -
                    end
         | 
| 677 | 
            +
                  # Convenience method to convert GRPC keys to Gcloud keys.
         | 
| 678 | 
            +
                  def to_gcloud_keys grpc_keys
         | 
| 679 | 
            +
                    # Keys are not nested in an object like entities are.
         | 
| 680 | 
            +
                    Array(grpc_keys).map { |key| Key.from_grpc key }
         | 
| 478 681 | 
             
                  end
         | 
| 479 682 |  | 
| 480 683 | 
             
                  def check_consistency! consistency
         |