@@ -27,6 +27,7 @@ import (
27
27
"fmt"
28
28
"strconv"
29
29
"strings"
30
+ "time"
30
31
31
32
"github.com/spf13/cobra"
32
33
@@ -59,8 +60,20 @@ const (
59
60
leaseDuration validProperty = "LeaseDuration"
60
61
leaseStatus validProperty = "LeaseStatus"
61
62
archiveStatus validProperty = "ArchiveStatus"
63
+
64
+ versionIdTimeFormat = "2006-01-02T15:04:05.9999999Z"
62
65
)
63
66
67
+ // containsProperty checks if the property array contains a valid property
68
+ func containsProperty (properties []validProperty , prop validProperty ) bool {
69
+ for _ , item := range properties {
70
+ if item == prop {
71
+ return true
72
+ }
73
+ }
74
+ return false
75
+ }
76
+
64
77
// validProperties returns an array of possible values for the validProperty const type.
65
78
func validProperties () []validProperty {
66
79
return []validProperty {lastModifiedTime , versionId , blobType , blobAccessTier ,
@@ -237,7 +250,10 @@ func (cooked cookedListCmdArgs) HandleListContainerCommand() (err error) {
237
250
}
238
251
}
239
252
240
- traverser , err := InitResourceTraverser (source , cooked .location , & ctx , & credentialInfo , common .ESymlinkHandlingType .Skip (), nil , true , true , false , common .EPermanentDeleteOption .None (), func (common.EntityType ) {}, nil , false , common .ESyncHashType .None (), common .EPreservePermissionsOption .None (), common .LogNone , common.CpkOptions {}, nil , false , cooked .trailingDot , nil , nil )
253
+ // check if user wants to get version id
254
+ shouldGetVersionId := containsProperty (cooked .properties , versionId )
255
+
256
+ traverser , err := InitResourceTraverser (source , cooked .location , & ctx , & credentialInfo , common .ESymlinkHandlingType .Skip (), nil , true , true , false , common .EPermanentDeleteOption .None (), func (common.EntityType ) {}, nil , false , common .ESyncHashType .None (), common .EPreservePermissionsOption .None (), common .LogNone , common.CpkOptions {}, nil , false , cooked .trailingDot , nil , nil , shouldGetVersionId )
241
257
242
258
if err != nil {
243
259
return fmt .Errorf ("failed to initialize traverser: %s" , err .Error ())
@@ -246,6 +262,12 @@ func (cooked cookedListCmdArgs) HandleListContainerCommand() (err error) {
246
262
var fileCount int64 = 0
247
263
var sizeCount int64 = 0
248
264
265
+ type versionIdObject struct {
266
+ versionId string
267
+ fileSize int64
268
+ }
269
+ objectVer := make (map [string ]versionIdObject )
270
+
249
271
processor := func (object StoredObject ) error {
250
272
path := object .relativePath
251
273
if object .entityType == common .EEntityType .Folder () {
@@ -266,6 +288,34 @@ func (cooked cookedListCmdArgs) HandleListContainerCommand() (err error) {
266
288
}
267
289
268
290
if cooked .RunningTally {
291
+ if shouldGetVersionId {
292
+ // get new version id object
293
+ updatedVersionId := versionIdObject {
294
+ versionId : object .blobVersionID ,
295
+ fileSize : object .size ,
296
+ }
297
+
298
+ // there exists a current version id of the object
299
+ if currentVersionId , ok := objectVer [object .relativePath ]; ok {
300
+ // get current version id time
301
+ currentVid , _ := time .Parse (versionIdTimeFormat , currentVersionId .versionId )
302
+
303
+ // get new version id time
304
+ newVid , _ := time .Parse (versionIdTimeFormat , object .blobVersionID )
305
+
306
+ // if new vid came after the current vid, then it is the latest version
307
+ // update the objectVer with the latest version
308
+ // we will also remove sizeCount and fileCount of current object, allowing
309
+ // the updated sizeCount and fileCount to be added at line 320
310
+ if newVid .After (currentVid ) {
311
+ sizeCount -= currentVersionId .fileSize // remove size of current object
312
+ fileCount -- // remove current object file count
313
+ objectVer [object .relativePath ] = updatedVersionId
314
+ }
315
+ } else {
316
+ objectVer [object .relativePath ] = updatedVersionId
317
+ }
318
+ }
269
319
fileCount ++
270
320
sizeCount += object .size
271
321
}
0 commit comments