lib/google/cloud/storage/file.rb in google-cloud-storage-1.3.0 vs lib/google/cloud/storage/file.rb in google-cloud-storage-1.4.0

- old
+ new

@@ -312,14 +312,14 @@ @gapi.storage_class end ## # Updates how the file is stored and determines the SLA and the cost of - # storage. Values include `:multi_regional`, `:regional`, `:nearline`, - # `:coldline`, `:standard`, and `:dra` (Durable Reduced Availability), - # as well as the strings returned by {File#storage_class} or - # {Bucket#storage_class}. For more information, see [Storage + # storage. Accepted values include `:multi_regional`, `:regional`, + # `:nearline`, and `:coldline`, as well as the equivalent strings + # returned by {File#storage_class} or {Bucket#storage_class}. For more + # information, see [Storage # Classes](https://cloud.google.com/storage/docs/storage-classes) and # [Per-Object Storage # Class](https://cloud.google.com/storage/docs/per-object-storage-class). # The default value is the default storage class for the bucket. See # {Bucket#storage_class}. @@ -328,10 +328,49 @@ @gapi.storage_class = storage_class_for(storage_class) update_gapi! :storage_class end ## + # Retrieves a list of versioned files for the current object. + # + # Useful for listing archived versions of the file, restoring the live + # version of the file to an older version, or deleting an archived + # version. You can turn versioning on or off for a bucket at any time + # with {Bucket#versioning=}. Turning versioning off leaves existing file + # versions in place and causes the bucket to stop accumulating new + # archived object versions. (See {Bucket#versioning} and + # {File#generation}) + # + # @see https://cloud.google.com/storage/docs/object-versioning Object + # Versioning + # + # @return [Array<Google::Cloud::Storage::File>] (See + # {Google::Cloud::Storage::File::List}) + # + # @example + # require "google/cloud/storage" + # + # storage = Google::Cloud::Storage.new + # + # bucket = storage.bucket "my-bucket" + # + # file = bucket.file "path/to/my-file.ext" + # file.generation #=> 1234567890 + # file.generations.each do |versioned_file| + # versioned_file.generation + # end + # + def generations + ensure_service! + gapi = service.list_files bucket, prefix: name, + versions: true, + user_project: user_project + File::List.from_gapi gapi, service, bucket, name, nil, nil, true, + user_project: user_project + end + + ## # Updates the file with changes made in the given block in a single # PATCH request. The following attributes may be set: {#cache_control=}, # {#content_disposition=}, {#content_encoding=}, {#content_language=}, # {#content_type=}, and {#metadata=}. The {#metadata} hash accessible in # the block is completely mutable and will be included in the request. @@ -637,10 +676,15 @@ ## # Permanently deletes the file. # # @return [Boolean] Returns `true` if the file was deleted. + # @param [Boolean, Integer] generation Specify a version of the file to + # delete. When `true`, it will delete the version returned by + # {#generation}. The default behavior is to delete the latest version + # of the file (regardless of the version to which the file is set, + # which is the version returned by {#generation}.) # # @example # require "google/cloud/storage" # # storage = Google::Cloud::Storage.new @@ -648,13 +692,35 @@ # bucket = storage.bucket "my-bucket" # # file = bucket.file "path/to/my-file.ext" # file.delete # - def delete + # @example The file's generation can used by passing `true`: + # require "google/cloud/storage" + # + # storage = Google::Cloud::Storage.new + # + # bucket = storage.bucket "my-bucket" + # + # file = bucket.file "path/to/my-file.ext" + # file.delete generation: true + # + # @example A generation can also be specified: + # require "google/cloud/storage" + # + # storage = Google::Cloud::Storage.new + # + # bucket = storage.bucket "my-bucket" + # + # file = bucket.file "path/to/my-file.ext" + # file.delete generation: 123456 + # + def delete generation: nil + generation = self.generation if generation == true ensure_service! - service.delete_file bucket, name, user_project: user_project + service.delete_file bucket, name, generation: generation, + user_project: user_project true end ## # Public URL to access the file. If the file is not public, requests to @@ -844,17 +910,80 @@ @acl ||= File::Acl.new self end ## # Reloads the file with current data from the Storage service. - def reload! + # + # @param [Boolean, Integer] generation Specify a version of the file to + # reload with. When `true`, it will reload the version returned by + # {#generation}. The default behavior is to reload with the latest + # version of the file (regardless of the version to which the file is + # set, which is the version returned by {#generation}.) + # + # @example + # require "google/cloud/storage" + # + # storage = Google::Cloud::Storage.new + # + # bucket = storage.bucket "my-bucket" + # + # file = bucket.file "path/to/my-file.ext" + # file.reload! + # + # @example The file's generation can used by passing `true`: + # require "google/cloud/storage" + # + # storage = Google::Cloud::Storage.new + # + # bucket = storage.bucket "my-bucket" + # + # file = bucket.file "path/to/my-file.ext", generation: 123456 + # file.reload! generation: true + # + # @example A generation can also be specified: + # require "google/cloud/storage" + # + # storage = Google::Cloud::Storage.new + # + # bucket = storage.bucket "my-bucket" + # + # file = bucket.file "path/to/my-file.ext", generation: 123456 + # file.reload! generation: 123457 + # + def reload! generation: nil + generation = self.generation if generation == true ensure_service! - @gapi = service.get_file bucket, name, user_project: user_project + @gapi = service.get_file bucket, name, generation: generation, + user_project: user_project + # If NotFound then lazy will never be unset + @lazy = nil + self end alias_method :refresh!, :reload! ## + # Determines whether the file exists in the Storage service. + def exists? + # Always true if we have a grpc object + return true unless lazy? + # If we have a value, return it + return @exists unless @exists.nil? + ensure_gapi! + @exists = true + rescue Google::Cloud::NotFoundError + @exists = false + end + + ## + # @private + # Determines whether the file was created without retrieving the + # resource record from the API. + def lazy? + @lazy + end + + ## # @private URI of the location and file name in the format of # <code>gs://my-bucket/file-name.json</code>. def to_gs_url "gs://#{bucket}/#{name}" end @@ -867,18 +996,41 @@ f.service = service f.user_project = user_project end end + ## + # @private New lazy Bucket object without making an HTTP request. + def self.new_lazy bucket, name, service, generation: nil, + user_project: nil + # TODO: raise if name is nil? + new.tap do |f| + f.gapi.bucket = bucket + f.gapi.name = name + f.gapi.generation = generation + f.service = service + f.user_project = user_project + f.instance_variable_set :@lazy, true + end + end + protected ## # Raise an error unless an active service is available. def ensure_service! fail "Must have active connection" unless service end + ## + # Ensures the Google::Apis::StorageV1::Bucket object exists. + def ensure_gapi! + ensure_service! + return unless lazy? + reload! generation: true + end + def update_gapi! *attributes attributes.flatten! return if attributes.empty? update_gapi = gapi_from_attrs attributes return if update_gapi.nil? @@ -929,11 +1081,11 @@ end def verify_file! file, verify = :md5 verify_md5 = verify == :md5 || verify == :all verify_crc32c = verify == :crc32c || verify == :all - Verifier.verify_md5! self, file if verify_md5 - Verifier.verify_crc32c! self, file if verify_crc32c + Verifier.verify_md5! self, file if verify_md5 && md5 + Verifier.verify_crc32c! self, file if verify_crc32c && crc32c file end def storage_class_for str return nil if str.nil?