diff --git a/CHANGELOG.md b/CHANGELOG.md index ad1bff2..07a2e8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [Unreleased] ### Added +* PR #13 copy with preconditions by @rfb. ### Changed diff --git a/src/clj_gcloud/storage.clj b/src/clj_gcloud/storage.clj index ea1538b..3fd03c7 100644 --- a/src/clj_gcloud/storage.clj +++ b/src/clj_gcloud/storage.clj @@ -105,9 +105,23 @@ (.build builder))) (defn copy - [^Storage storage ^BlobId source-blob-id ^BlobId target-blob-id] - (-> (.copy storage (Storage$CopyRequest/of source-blob-id target-blob-id)) - (.getResult))) + ([storage source-blob-id target-blob-id] + (copy storage source-blob-id target-blob-id nil)) + ([^Storage storage ^BlobId source-blob-id ^BlobId target-blob-id options] + (let [cr (if (:with-precondition options) + ;; Copy blobs within cloud storage using preconditions recommended in Google Cloud Storage guides + ;; See: https://cloud.google.com/storage/docs/copying-renaming-moving-objects#storage-copy-object-java + (let [precondition (if-let [target (.get storage target-blob-id)] + (Storage$BlobTargetOption/generationMatch (.getGeneration target)) + (Storage$BlobTargetOption/doesNotExist)) + ^Iterable target-opts (into-array Storage$BlobTargetOption [precondition])] + (-> (Storage$CopyRequest/newBuilder) + (.setSource source-blob-id) + (.setTarget target-blob-id target-opts) + .build)) + (Storage$CopyRequest/of source-blob-id target-blob-id))] + (-> (.copy storage cr) + (.getResult))))) (defn create-blob [^Storage storage ^BlobInfo blob-info] @@ -229,5 +243,10 @@ Usage : (download-file-from-storage storage-client 'gs://mybucket/myfolder/.../myfile' 'mylocalfile')" [^Storage storage source-gs-uri dest-local-path & _options] - (let [blob (->> source-gs-uri ->blob-id (get-blob storage))] - (.downloadTo blob (Paths/get dest-local-path (make-array String 0)) (into-array Blob$BlobSourceOption [])))) + (let [^Blob blob (->> source-gs-uri ->blob-id (get-blob storage)) + path (Paths/get dest-local-path (make-array String 0)) + ;; this resolves reflection but it's pretty ugly: + ;; ^"[Lcom.google.cloud.storage.Blob$BlobSourceOption;" opts (into-array Blob$BlobSourceOption []) + ;; for now skip it, since we pass no options anyway + ] + (.downloadTo blob path))) diff --git a/test/clj_gcloud/storage_test.clj b/test/clj_gcloud/storage_test.clj index 5fb8388..584e19a 100644 --- a/test/clj_gcloud/storage_test.clj +++ b/test/clj_gcloud/storage_test.clj @@ -58,4 +58,3 @@ (is (delete-blob *storage* (.getBlobId blob))) (is (= 0 (count (ls *storage* dest-uri))))) (.delete tmp)))) -