func (c *Carves) CompleteBlock(sessionid string) error {
	carve, err := c.GetBySession(sessionid)
	if err != nil {
		return fmt.Errorf("getCarveBySessionID %v", err)
	}
	if err := c.DB.Model(&carve).Update("completed_blocks", carve.CompletedBlocks+1).Error; err != nil {
		return fmt.Errorf("Update %v", err)
	}
	return nil
}
CompleteBlock to increase one block for a carve
package carves
import (
	"bytes"
	"encoding/base64"
	"fmt"
	"log"
	"os"
	"strings"
	"time"
	"github.com/jinzhu/gorm"
)
const (
	StatusQueried string = "QUERIED"
	StatusInitialized string = "INITIALIZED"
	StatusInProgress string = "IN PROGRESS"
	StatusCompleted string = "COMPLETED"
)
var (
	CompressionHeader = []byte{0x28, 0xb5, 0x2f, 0xfd}
)
type MappedCarves map[string][]CarvedFile
type QueriedCarve struct {
	Name    string
	Path    string
	Status  string
	Creator string
}
type CarvedFile struct {
	gorm.Model
	CarveID         string `gorm:"unique;index"`
	RequestID       string
	SessionID       string
	UUID            string `gorm:"index"`
	Environment     string
	CarveSize       int
	BlockSize       int
	TotalBlocks     int
	CompletedBlocks int
	Status          string
	CompletedAt     time.Time
}
type CarvedBlock struct {
	gorm.Model
	RequestID   string `gorm:"index"`
	SessionID   string `gorm:"index"`
	Environment string
	BlockID     int
	Data        string
	Size        int
}
type CarveResult struct {
	Size int64
	File string
}
type Carves struct {
	DB *gorm.DB
}
func CreateFileCarves(backend *gorm.DB) *Carves {
	var c *Carves
	c = &Carves{DB: backend}
	if err := backend.AutoMigrate(CarvedFile{}).Error; err != nil {
		log.Fatalf("Failed to AutoMigrate table (carved_files): %v", err)
	}
	if err := backend.AutoMigrate(CarvedBlock{}).Error; err != nil {
		log.Fatalf("Failed to AutoMigrate table (carved_blocks): %v", err)
	}
	return c
}
func (c *Carves) CreateCarve(carve CarvedFile) error {
	if c.DB.NewRecord(carve) {
		return c.DB.Create(&carve).Error  
	}
	return fmt.Errorf("db.NewRecord did not return true")
}
func (c *Carves) CheckCarve(sessionid, requestid string) bool {
	carve, err := c.GetBySession(sessionid)
	if err != nil {
		return false
	}
	return (carve.RequestID == strings.TrimSpace(requestid))
}
func (c *Carves) CreateBlock(block CarvedBlock) error {
	if c.DB.NewRecord(block) {
		return c.DB.Create(&block).Error  
	}
	return fmt.Errorf("db.NewRecord did not return true")
}
func (c *Carves) Delete(carveid string) error {
	carve, err := c.GetByCarve(carveid)
	if err != nil {
		return fmt.Errorf("getCarveByID %v", err)
	}
	if err := c.DB.Unscoped().Delete(&carve).Error; err != nil {
		return fmt.Errorf("Delete %v", err)
	}
	return nil
}
func (c *Carves) DeleteBlocks(sessionid string) error {
	blocks, err := c.GetBlocks(sessionid)
	if err != nil {
		return fmt.Errorf("getBlocksBySessionID %v", err)
	}
	for _, b := range blocks {
		if err := c.DB.Unscoped().Delete(&b).Error; err != nil {
			return fmt.Errorf("Delete %v", err)
		}
	}
	return nil
}
func (c *Carves) GetByCarve(carveid string) (CarvedFile, error) {
	var carve CarvedFile
	if err := c.DB.Where("carve_id = ?", carveid).Find(&carve).Error; err != nil {
		return carve, err
	}
	return carve, nil
}
func (c *Carves) GetBySession(sessionid string) (CarvedFile, error) {
	var carve CarvedFile
	if err := c.DB.Where("session_id = ?", sessionid).Find(&carve).Error; err != nil {
		return carve, err
	}
	return carve, nil
}
func (c *Carves) GetByRequest(requestid string) ([]CarvedFile, error) {
	var carves []CarvedFile
	if err := c.DB.Where("request_id = ?", requestid).Find(&carves).Error; err != nil {
		return carves, err
	}
	return carves, nil
}
func (c *Carves) GetByQuery(name string) ([]CarvedFile, error) {
	return c.GetByRequest(name)
}
func (c *Carves) GetBlocks(sessionid string) ([]CarvedBlock, error) {
	var blocks []CarvedBlock
	if err := c.DB.Where("session_id = ?", sessionid).Order("block_id").Find(&blocks).Error; err != nil {
		return blocks, err
	}
	return blocks, nil
}
func (c *Carves) CheckCompression(block CarvedBlock) (bool, error) {
	if block.BlockID != 0 {
		return false, fmt.Errorf("block_id is not 0 (%d)", block.BlockID)
	}
	compressionCheck, err := base64.StdEncoding.DecodeString(block.Data)
	if err != nil {
		return false, fmt.Errorf("Decoding first block %v", err)
	}
	if bytes.Compare(compressionCheck[:4], CompressionHeader) == 0 {
		return true, nil
	}
	return false, nil
}
func (c *Carves) GetNodeCarves(uuid string) ([]CarvedFile, error) {
	var carves []CarvedFile
	if err := c.DB.Where("uuid = ?", uuid).Find(&carves).Error; err != nil {
		return carves, err
	}
	return carves, nil
}
func (c *Carves) ChangeStatus(status, sessionid string) error {
	carve, err := c.GetBySession(sessionid)
	if err != nil {
		return fmt.Errorf("getCarveBySessionID %v", err)
	}
	if err := c.DB.Model(&carve).Update("status", status).Error; err != nil {
		return fmt.Errorf("Update %v", err)
	}
	if status == StatusCompleted {
		if err := c.DB.Model(&carve).Update("completed_at", time.Now()).Error; err != nil {
			return fmt.Errorf("Update %v", err)
		}
	}
	return nil
}