github.com/hoffie/larasync@v0.0.0-20151025221940-0384d2bddcef/repository/content/uuidStorage.go (about)

     1  package content
     2  
     3  import (
     4  	"crypto/rand"
     5  	"crypto/sha512"
     6  	"encoding/hex"
     7  	"os"
     8  )
     9  
    10  // UUIDStorage is a base struct which implements functionality
    11  // to find new UUIDs for the system.
    12  type UUIDStorage struct {
    13  	Storage
    14  }
    15  
    16  // NewUUIDStorage wraps a given Storage object and returns a
    17  // UUIDStorage object.
    18  func NewUUIDStorage(storage Storage) *UUIDStorage {
    19  	return &UUIDStorage{
    20  		Storage: storage,
    21  	}
    22  }
    23  
    24  // FindFreeUUID generates a new UUID; it tries to avoid
    25  // local collisions.
    26  func (m *UUIDStorage) FindFreeUUID() ([]byte, error) {
    27  	hostname := os.Getenv("HOSTNAME")
    28  	rnd := make([]byte, 32)
    29  	for {
    30  		_, err := rand.Read(rnd)
    31  		if err != nil {
    32  			return nil, err
    33  		}
    34  		hasher := sha512.New()
    35  		hasher.Write([]byte(hostname))
    36  		hasher.Write(rnd)
    37  		hash := hasher.Sum(nil)
    38  		hasUUID := m.HasUUID(hash)
    39  		if err != nil {
    40  			return nil, err
    41  		}
    42  		if !hasUUID {
    43  			return hash, nil
    44  		}
    45  	}
    46  }
    47  
    48  // HasUUID checks if the given UUID is already in use in this repository;
    49  // this is a local-only check.
    50  func (m *UUIDStorage) HasUUID(hash []byte) bool {
    51  	UUID := hex.EncodeToString(hash)
    52  	return m.Exists(UUID)
    53  }