<commit_before>package arn

import (
	"sort"
	"strings"

	"github.com/aerogo/flow"
)

// MinimumStringSimilarity is the minimum JaroWinkler distance we accept for search results.
const MinimumStringSimilarity = 0.89

// popularityDamping reduces the factor of popularity in search results.
const popularityDamping = 0.048

// SearchResult ...
type SearchResult struct {
	obj        interface{}
	similarity float64
}

// Search is a fuzzy search.
func Search(term string, maxUsers, maxAnime, maxPosts, maxThreads, maxTracks int, maxCharacters int) ([]*User, []*Anime, []*Post, []*Thread, []*SoundTrack, []*Character) {
	term = strings.ToLower(term)

	if term == "" {
		return nil, nil, nil, nil, nil, nil
	}

	var userResults []*User
	var animeResults []*Anime
	var postResults []*Post
	var threadResults []*Thread
	var trackResults []*SoundTrack
	var characterResults []*Character

	flow.Parallel(func() {
		userResults = SearchUsers(term, maxUsers)
	}, func() {
		animeResults = SearchAnime(term, maxAnime)
	}, func() {
		postResults = SearchPosts(term, maxPosts)
	}, func() {
		threadResults = SearchThreads(term, maxThreads)
	}, func() {
		trackResults = SearchSoundTracks(term, maxTracks)
	}, func() {
		characterResults = SearchCharacters(term, maxCharacters)
	})

	return userResults, animeResults, postResults, threadResults, trackResults, characterResults
}

// SearchCharacters searches all characters.
func SearchCharacters(term string, maxLength int) []*Character {
	var results []*Character

	for character := range StreamCharacters() {
		text := strings.ToLower(character.Name)

		if !strings.Contains(text, term) {
			continue
		}

		results = append(results, character)
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].Name > results[j].Name
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	return results
}

// SearchSoundTracks searches all soundtracks.
func SearchSoundTracks(term string, maxLength int) []*SoundTrack {
	var results []*SearchResult

	for track := range StreamSoundTracks() {
		text := strings.ToLower(track.Title)

		// Similarity check
		similarity := AdvancedStringSimilarity(term, text)

		if similarity >= MinimumStringSimilarity {
			results = append(results, &SearchResult{
				obj:        track,
				similarity: similarity,
			})
			continue
		}
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].similarity > results[j].similarity
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	// Final list
	final := make([]*SoundTrack, len(results), len(results))

	for i, result := range results {
		final[i] = result.obj.(*SoundTrack)
	}

	return final
}

// SearchPosts searches all posts.
func SearchPosts(term string, maxLength int) []*Post {
	var results []*Post

	for post := range StreamPosts() {
		text := strings.ToLower(post.Text)

		if !strings.Contains(text, term) {
			continue
		}

		results = append(results, post)
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].Created > results[j].Created
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	return results
}

// SearchThreads searches all threads.
func SearchThreads(term string, maxLength int) []*Thread {
	var results []*Thread

	for thread := range StreamThreads() {
		text := strings.ToLower(thread.Text)

		if strings.Contains(text, term) {
			results = append(results, thread)
			continue
		}

		text = strings.ToLower(thread.Title)

		if strings.Contains(text, term) {
			results = append(results, thread)
			continue
		}
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].Created > results[j].Created
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	return results
}

// SearchUsers searches all users.
func SearchUsers(term string, maxLength int) []*User {
	var results []*SearchResult

	for user := range StreamUsers() {
		text := strings.ToLower(user.Nick)

		// Similarity check
		similarity := AdvancedStringSimilarity(term, text)

		if similarity < MinimumStringSimilarity {
			continue
		}

		results = append(results, &SearchResult{
			obj:        user,
			similarity: similarity,
		})
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].similarity > results[j].similarity
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	// Final list
	final := make([]*User, len(results), len(results))

	for i, result := range results {
		final[i] = result.obj.(*User)
	}

	return final
}

// SearchAnime searches all anime.
func SearchAnime(term string, maxLength int) []*Anime {
	var results []*SearchResult

	check := func(text string) float64 {
		return AdvancedStringSimilarity(term, RemoveSpecialCharacters(strings.ToLower(text)))
	}

	add := func(anime *Anime, similarity float64) {
		similarity += float64(anime.Popularity.Total()) * popularityDamping

		results = append(results, &SearchResult{
			obj:        anime,
			similarity: similarity,
		})
	}

	for anime := range StreamAnime() {
		// Canonical title
		similarity := check(anime.Title.Canonical)

		if similarity >= MinimumStringSimilarity {
			add(anime, similarity)
			continue
		}

		// English
		similarity = check(anime.Title.English)

		if similarity >= MinimumStringSimilarity {
			add(anime, similarity)
			continue
		}

		// Synonyms
		for _, synonym := range anime.Title.Synonyms {
			similarity := check(synonym)

			if similarity >= MinimumStringSimilarity {
				add(anime, similarity)
				goto nextAnime
			}
		}

		// Japanese
		similarity = check(anime.Title.Japanese)

		if similarity >= MinimumStringSimilarity {
			add(anime, similarity)
			continue
		}

	nextAnime:
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].similarity > results[j].similarity
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	// Final list
	final := make([]*Anime, len(results), len(results))

	for i, result := range results {
		final[i] = result.obj.(*Anime)
	}

	return final
}
<commit_msg>Disabled character search for now<commit_after>package arn

import (
	"sort"
	"strings"

	"github.com/aerogo/flow"
)

// MinimumStringSimilarity is the minimum JaroWinkler distance we accept for search results.
const MinimumStringSimilarity = 0.89

// popularityDamping reduces the factor of popularity in search results.
const popularityDamping = 0.048

// SearchResult ...
type SearchResult struct {
	obj        interface{}
	similarity float64
}

// Search is a fuzzy search.
func Search(term string, maxUsers, maxAnime, maxPosts, maxThreads, maxTracks int, maxCharacters int) ([]*User, []*Anime, []*Post, []*Thread, []*SoundTrack, []*Character) {
	term = strings.ToLower(term)

	if term == "" {
		return nil, nil, nil, nil, nil, nil
	}

	var userResults []*User
	var animeResults []*Anime
	var postResults []*Post
	var threadResults []*Thread
	var trackResults []*SoundTrack
	var characterResults []*Character

	flow.Parallel(func() {
		userResults = SearchUsers(term, maxUsers)
	}, func() {
		animeResults = SearchAnime(term, maxAnime)
	}, func() {
		postResults = SearchPosts(term, maxPosts)
	}, func() {
		threadResults = SearchThreads(term, maxThreads)
	}, func() {
		trackResults = SearchSoundTracks(term, maxTracks)
	}, func() {
		characterResults = SearchCharacters(term, maxCharacters)
	})

	return userResults, animeResults, postResults, threadResults, trackResults, characterResults
}

// SearchCharacters searches all characters.
func SearchCharacters(term string, maxLength int) []*Character {
	if maxLength == 0 {
		return nil
	}

	var results []*Character

	for character := range StreamCharacters() {
		text := strings.ToLower(character.Name)

		if !strings.Contains(text, term) {
			continue
		}

		results = append(results, character)
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].Name > results[j].Name
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	return results
}

// SearchSoundTracks searches all soundtracks.
func SearchSoundTracks(term string, maxLength int) []*SoundTrack {
	var results []*SearchResult

	for track := range StreamSoundTracks() {
		text := strings.ToLower(track.Title)

		// Similarity check
		similarity := AdvancedStringSimilarity(term, text)

		if similarity >= MinimumStringSimilarity {
			results = append(results, &SearchResult{
				obj:        track,
				similarity: similarity,
			})
			continue
		}
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].similarity > results[j].similarity
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	// Final list
	final := make([]*SoundTrack, len(results), len(results))

	for i, result := range results {
		final[i] = result.obj.(*SoundTrack)
	}

	return final
}

// SearchPosts searches all posts.
func SearchPosts(term string, maxLength int) []*Post {
	var results []*Post

	for post := range StreamPosts() {
		text := strings.ToLower(post.Text)

		if !strings.Contains(text, term) {
			continue
		}

		results = append(results, post)
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].Created > results[j].Created
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	return results
}

// SearchThreads searches all threads.
func SearchThreads(term string, maxLength int) []*Thread {
	var results []*Thread

	for thread := range StreamThreads() {
		text := strings.ToLower(thread.Text)

		if strings.Contains(text, term) {
			results = append(results, thread)
			continue
		}

		text = strings.ToLower(thread.Title)

		if strings.Contains(text, term) {
			results = append(results, thread)
			continue
		}
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].Created > results[j].Created
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	return results
}

// SearchUsers searches all users.
func SearchUsers(term string, maxLength int) []*User {
	var results []*SearchResult

	for user := range StreamUsers() {
		text := strings.ToLower(user.Nick)

		// Similarity check
		similarity := AdvancedStringSimilarity(term, text)

		if similarity < MinimumStringSimilarity {
			continue
		}

		results = append(results, &SearchResult{
			obj:        user,
			similarity: similarity,
		})
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].similarity > results[j].similarity
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	// Final list
	final := make([]*User, len(results), len(results))

	for i, result := range results {
		final[i] = result.obj.(*User)
	}

	return final
}

// SearchAnime searches all anime.
func SearchAnime(term string, maxLength int) []*Anime {
	var results []*SearchResult

	check := func(text string) float64 {
		return AdvancedStringSimilarity(term, RemoveSpecialCharacters(strings.ToLower(text)))
	}

	add := func(anime *Anime, similarity float64) {
		similarity += float64(anime.Popularity.Total()) * popularityDamping

		results = append(results, &SearchResult{
			obj:        anime,
			similarity: similarity,
		})
	}

	for anime := range StreamAnime() {
		// Canonical title
		similarity := check(anime.Title.Canonical)

		if similarity >= MinimumStringSimilarity {
			add(anime, similarity)
			continue
		}

		// English
		similarity = check(anime.Title.English)

		if similarity >= MinimumStringSimilarity {
			add(anime, similarity)
			continue
		}

		// Synonyms
		for _, synonym := range anime.Title.Synonyms {
			similarity := check(synonym)

			if similarity >= MinimumStringSimilarity {
				add(anime, similarity)
				goto nextAnime
			}
		}

		// Japanese
		similarity = check(anime.Title.Japanese)

		if similarity >= MinimumStringSimilarity {
			add(anime, similarity)
			continue
		}

	nextAnime:
	}

	// Sort
	sort.Slice(results, func(i, j int) bool {
		return results[i].similarity > results[j].similarity
	})

	// Limit
	if len(results) >= maxLength {
		results = results[:maxLength]
	}

	// Final list
	final := make([]*Anime, len(results), len(results))

	for i, result := range results {
		final[i] = result.obj.(*Anime)
	}

	return final
}
<|endoftext|>


<commit_before>package processor

import "github.com/chris-wood/spud/codec"
import "github.com/chris-wood/spud/messages"
import "github.com/chris-wood/spud/messages/validation"
import "github.com/chris-wood/spud/messages/validation/publickey"
import "crypto/rand"
import "crypto/rsa"
import "crypto/sha256"
import "crypto/x509"
import "crypto"
import "hash"

type CryptoProcessor interface {
    Sign(msg messages.Message) ([]byte, error)
    Verify(request, response messages.Message) bool
    ProcessorDetails() validation.ValidationAlgorithm
    Hasher() hash.Hash
}

type RSAProcessor struct {
    privateKey *rsa.PrivateKey
    publicKey rsa.PublicKey
}

type processorError struct {
    problem string
}

func (p processorError) Error() string {
    return p.problem
}

func NewRSAProcessor(keySize int) (RSAProcessor, error) {
    var result RSAProcessor

    if keySize != 2048 && keySize != 4096 {
        return result, processorError{"Invalid key length provided: " + string(keySize)}
    }

    privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
    if err != nil {
        return result, processorError{"Failed to generate a private key: " + err.Error()}
    }

    publicKey := privateKey.PublicKey

    return RSAProcessor{privateKey: privateKey, publicKey: publicKey}, nil
}

func (p RSAProcessor) Sign(msg messages.Message) ([]byte, error) {
    digest := msg.HashSensitiveRegion(sha256.New())
    signature, err := rsa.SignPKCS1v15(rand.Reader, p.privateKey, crypto.SHA256, digest)
    return signature, err
}

func (p RSAProcessor) Verify(request, response messages.Message) bool {
    validationPayload := response.GetValidationPayload()
    validationAlgorithm := response.GetValidationAlgorithm()

    var key *rsa.PublicKey
    switch validationAlgorithm.Type() {
    case codec.T_RSA_SHA256:
        responseKey := validationAlgorithm.GetPublicKey()
        rawKey, err := x509.ParsePKIXPublicKey(responseKey.Value())
        if err != nil {
            return false
        }
        key = rawKey.(*rsa.PublicKey)
    default:
        return false
    }

    signature := validationPayload.Value()
    digest := response.HashSensitiveRegion(sha256.New())

    err := rsa.VerifyPKCS1v15(key, crypto.SHA256, digest, signature)
    return err != nil
}

func (p RSAProcessor) ProcessorDetails() validation.ValidationAlgorithm {
    var result validation.ValidationAlgorithm
    publicKeyBytes, err := x509.MarshalPKIXPublicKey(p.publicKey)
    if err != nil {
        return result
    }

    publicKey := publickey.Create(publicKeyBytes)
    va := validation.NewValidationAlgorithmFromPublickey(codec.T_RSA_SHA256, publicKey, 0)
    return va
}

func (p RSAProcessor) Hasher() hash.Hash {
    return sha256.New()
}
<commit_msg>ValidationAlgorithm information not encoded correctly.<commit_after>package processor

import "github.com/chris-wood/spud/codec"
import "github.com/chris-wood/spud/messages"
import "github.com/chris-wood/spud/messages/validation"
import "github.com/chris-wood/spud/messages/validation/publickey"
import "crypto/rand"
import "crypto/rsa"
import "crypto/sha256"
import "crypto/x509"
import "crypto"
import "hash"
import "fmt"

type CryptoProcessor interface {
    Sign(msg messages.Message) ([]byte, error)
    Verify(request, response messages.Message) bool
    ProcessorDetails() validation.ValidationAlgorithm
    Hasher() hash.Hash
}

type RSAProcessor struct {
    privateKey *rsa.PrivateKey
    publicKey rsa.PublicKey
}

type processorError struct {
    problem string
}

func (p processorError) Error() string {
    return fmt.Sprintf("%s", p.problem)
}

func NewRSAProcessor(keySize int) (RSAProcessor, error) {
    var result RSAProcessor

    if keySize != 2048 && keySize != 4096 {
        return result, processorError{"Invalid key length provided: " + string(keySize)}
    }

    privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
    if err != nil {
        return result, processorError{"Failed to generate a private key: " + err.Error()}
    }

    publicKey := privateKey.PublicKey

    return RSAProcessor{privateKey: privateKey, publicKey: publicKey}, nil
}

func (p RSAProcessor) Sign(msg messages.Message) ([]byte, error) {
    digest := msg.HashSensitiveRegion(sha256.New())
    signature, err := rsa.SignPKCS1v15(rand.Reader, p.privateKey, crypto.SHA256, digest)
    return signature, err
}

func (p RSAProcessor) Verify(request, response messages.Message) bool {
    validationPayload := response.GetValidationPayload()
    validationAlgorithm := response.GetValidationAlgorithm()

    var key *rsa.PublicKey
    switch validationAlgorithm.Type() {
    case codec.T_RSA_SHA256:
        responseKey := validationAlgorithm.GetPublicKey()
        rawKey, err := x509.ParsePKIXPublicKey(responseKey.Value())
        if err != nil {
            fmt.Println("error parsing public key")
            return false
        }
        key = rawKey.(*rsa.PublicKey)
    default:
        fmt.Println("invalid crypto type")
        return false
    }

    signature := validationPayload.Value()
    digest := response.HashSensitiveRegion(sha256.New())

    err := rsa.VerifyPKCS1v15(key, crypto.SHA256, digest, signature)
    return err != nil
}

func (p RSAProcessor) ProcessorDetails() validation.ValidationAlgorithm {
    var result validation.ValidationAlgorithm
    publicKeyBytes, err := x509.MarshalPKIXPublicKey(p.publicKey)
    if err != nil {
        return result
    }

    publicKey := publickey.Create(publicKeyBytes)
    va := validation.NewValidationAlgorithmFromPublickey(codec.T_RSA_SHA256, publicKey, 0)
    return va
}

func (p RSAProcessor) Hasher() hash.Hash {
    return sha256.New()
}
<|endoftext|>


<commit_before>package controllers

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
)

// VERSION is version of Tat.
const VERSION = "0.60.0"

// SystemController contains all methods about version
type SystemController struct{}

//GetVersion returns version of tat
func (*SystemController) GetVersion(ctx *gin.Context) {
	ctx.JSON(http.StatusOK, gin.H{"version": VERSION})
}

//GetCapabilites returns version of tat
func (*SystemController) GetCapabilites(ctx *gin.Context) {
	ctx.JSON(http.StatusOK, gin.H{
		"websocket_enabled":   viper.GetBool("websocket_enabled"),
		"username_from_email": viper.GetBool("username_from_email"),
	})
}
<commit_msg>[auto] bump version to v0.61.0<commit_after>package controllers

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
)

// VERSION is version of Tat.
const VERSION = "0.61.0"

// SystemController contains all methods about version
type SystemController struct{}

//GetVersion returns version of tat
func (*SystemController) GetVersion(ctx *gin.Context) {
	ctx.JSON(http.StatusOK, gin.H{"version": VERSION})
}

//GetCapabilites returns version of tat
func (*SystemController) GetCapabilites(ctx *gin.Context) {
	ctx.JSON(http.StatusOK, gin.H{
		"websocket_enabled":   viper.GetBool("websocket_enabled"),
		"username_from_email": viper.GetBool("username_from_email"),
	})
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	"github.com/fblanco/talks/cool/scheduler"
	"github.com/fblanco/talks/cool/utils"
)

var aduration utils.AtomicNotifiableDuration

func signalsHandler(wg *sync.WaitGroup, timeout time.Duration) {
	c := make(chan os.Signal)
	signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR2)

	// Block until a signal is received.
	s := <-c
	//changing healthCheck status return code, give time to clear active requests before exiting
	stop.Set()

	log.Printf("Signal '%s' received, letting requests finish", s)

	// wait for all pending request to finish, but don't wait more than "timeout"
	t := utils.WaitTimeout(wg, timeout)
	if t {
		log.Println("finished waiting because of time out, proceeding with cleanup")
	} else {
		log.Println("finished waiting all pending requests are done, proceeding with cleanup")
	}
	/* clean up here
	   (close db, files etc...)
	*/

	// signal assigned to restart behavior
	if s == syscall.SIGUSR2 {
		log.Println("restarting itself!")
		restart()
		return
	}

	log.Println("bye!")
	os.Exit(1)
}

func restart() {
	syscall.Exec(os.Args[0], os.Args, os.Environ())
}

var wg sync.WaitGroup
var stop utils.AtomicBool

var port = flag.String("port", "8001", "http server port")

const userInfoKey = 10

var authUser = map[string]int{"fabrizio": 1, "test": 2}

type userInfo struct {
	user string
	role int
}

func init() {
	flag.Parse()
	rand.Seed(time.Now().UnixNano())
	aduration.Set(10 * time.Second)
}

func main() {
	log.Println("starting up v4")
	go signalsHandler(&wg, 10*time.Second)
	http.HandleFunc("/do", checkInOut(authIt(logIt(doSomething), 1, 2)))
	http.HandleFunc("/do1", checkInOut(authIt(logIt(doSomething), 1)))
	http.HandleFunc("/do2", checkInOut(authIt(logIt(doSomething), 2)))

	scheduler.Schedule(mischief, &aduration)
	go changeDuration()
	log.Printf(http.ListenAndServe(":"+*port, nil).Error())

}

func mischief() {
	log.Println("firing SIGUSR2 signal to self")
	syscall.Kill(syscall.Getpid(), syscall.SIGUSR2)
}

// simulating config change for aduration variable
func changeDuration() {
	for {
		time.Sleep((time.Duration)(rand.Intn(10)) * time.Second)
		nd := (time.Duration)(rand.Intn(20)+1) * time.Second
		log.Printf("changed mischief execution schedule to every %v", nd)
		aduration.Set(nd)
	}
}

func doSomething(w http.ResponseWriter, r *http.Request) {
	st := time.Duration(rand.Intn(20)) * time.Second
	time.Sleep(st)
	fmt.Fprintf(w, "took a nap for %v\n", st)
}

func checkInOut(f http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		wg.Add(1)
		defer wg.Done()
		f(w, r)
	}
}

func logIt(f http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		t := time.Now()
		f(w, r)
		uinfo, ok := r.Context().Value(userInfoKey).(userInfo)
		if !ok {
			uinfo = userInfo{"n/a", -1}
		}
		log.Printf("user:%s, role:%d, m:%s, r:%s, ua:%s, et:%v", uinfo.user, uinfo.role, r.Method, r.RequestURI, r.UserAgent(), time.Since(t))
	}
}

func authIt(fn http.HandlerFunc, roles ...int) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		user := r.FormValue("u")
		role, ok := authUser[user]
		if !ok {
			fmt.Fprintf(w, "not Authorized")
			return
		}
		auth := false
		for _, rl := range roles {
			if role == rl {
				auth = true
				break

			}
		}
		if !auth {
			fmt.Fprintf(w, "not Authorized")
			return
		}

		ui := userInfo{user, role}
		ctx := context.WithValue(r.Context(), userInfoKey, ui)
		fn(w, r.WithContext(ctx))
	}
}
<commit_msg>small change to be consistent on the wrappers<commit_after>package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	"github.com/fblanco/talks/cool/scheduler"
	"github.com/fblanco/talks/cool/utils"
)

var aduration utils.AtomicNotifiableDuration

func signalsHandler(wg *sync.WaitGroup, timeout time.Duration) {
	c := make(chan os.Signal)
	signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR2)

	// Block until a signal is received.
	s := <-c
	//changing healthCheck status return code, give time to clear active requests before exiting
	stop.Set()

	log.Printf("Signal '%s' received, letting requests finish", s)

	// wait for all pending request to finish, but don't wait more than "timeout"
	t := utils.WaitTimeout(wg, timeout)
	if t {
		log.Println("finished waiting because of time out, proceeding with cleanup")
	} else {
		log.Println("finished waiting all pending requests are done, proceeding with cleanup")
	}
	/* clean up here
	   (close db, files etc...)
	*/

	// signal assigned to restart behavior
	if s == syscall.SIGUSR2 {
		log.Println("restarting itself!")
		restart()
		return
	}

	log.Println("bye!")
	os.Exit(1)
}

func restart() {
	syscall.Exec(os.Args[0], os.Args, os.Environ())
}

var wg sync.WaitGroup
var stop utils.AtomicBool

var port = flag.String("port", "8001", "http server port")

const userInfoKey = 10

var authUser = map[string]int{"fabrizio": 1, "test": 2}

type userInfo struct {
	user string
	role int
}

func init() {
	flag.Parse()
	rand.Seed(time.Now().UnixNano())
	aduration.Set(10 * time.Second)
}

func main() {
	log.Println("starting up v4")
	go signalsHandler(&wg, 10*time.Second)
	http.HandleFunc("/do", checkInOut(authIt(logIt(doSomething), 1, 2)))
	http.HandleFunc("/do1", checkInOut(authIt(logIt(doSomething), 1)))
	http.HandleFunc("/do2", checkInOut(authIt(logIt(doSomething), 2)))

	scheduler.Schedule(mischief, &aduration)
	go changeDuration()
	log.Printf(http.ListenAndServe(":"+*port, nil).Error())

}

func mischief() {
	log.Println("firing SIGUSR2 signal to self")
	syscall.Kill(syscall.Getpid(), syscall.SIGUSR2)
}

// simulating config change for aduration variable
func changeDuration() {
	for {
		time.Sleep((time.Duration)(rand.Intn(10)) * time.Second)
		nd := (time.Duration)(rand.Intn(20)+1) * time.Second
		log.Printf("changed mischief execution schedule to every %v", nd)
		aduration.Set(nd)
	}
}

func doSomething(w http.ResponseWriter, r *http.Request) {
	st := time.Duration(rand.Intn(20)) * time.Second
	time.Sleep(st)
	fmt.Fprintf(w, "took a nap for %v\n", st)
}

func checkInOut(f http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		wg.Add(1)
		defer wg.Done()
		f(w, r)
	}
}

func logIt(f http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		t := time.Now()
		f(w, r)
		uinfo, ok := r.Context().Value(userInfoKey).(userInfo)
		if !ok {
			uinfo = userInfo{"n/a", -1}
		}
		log.Printf("user:%s, role:%d, m:%s, r:%s, ua:%s, et:%v", uinfo.user, uinfo.role, r.Method, r.RequestURI, r.UserAgent(), time.Since(t))
	}
}

func authIt(f http.HandlerFunc, roles ...int) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		user := r.FormValue("u")
		role, ok := authUser[user]
		if !ok {
			fmt.Fprintf(w, "not Authorized")
			return
		}
		auth := false
		for _, rl := range roles {
			if role == rl {
				auth = true
				break

			}
		}
		if !auth {
			fmt.Fprintf(w, "not Authorized")
			return
		}

		ui := userInfo{user, role}
		ctx := context.WithValue(r.Context(), userInfoKey, ui)
		f(w, r.WithContext(ctx))
	}
}
<|endoftext|>


<commit_before>package commands

import (
	"errors"
	"fmt"
	"io"

	cmds "github.com/jbenet/go-ipfs/commands"
	core "github.com/jbenet/go-ipfs/core"
	internal "github.com/jbenet/go-ipfs/core/commands2/internal"
	importer "github.com/jbenet/go-ipfs/importer"
	dag "github.com/jbenet/go-ipfs/merkledag"
)

// Error indicating the max depth has been exceded.
var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded")

type AddOutput struct {
	Added []Object
}

var addCmd = &cmds.Command{
	Options: []cmds.Option{
		cmds.Option{[]string{"recursive", "r"}, cmds.Bool, "Must be specified when adding directories"},
	},
	Arguments: []cmds.Argument{
		cmds.Argument{"file", cmds.ArgFile, false, true, "The path to a file to be added to IPFS"},
	},
	Description: "Add an object to ipfs.",
	Help: `Adds contents of <path> to ipfs. Use -r to add directories.
    Note that directories are added recursively, to form the ipfs
    MerkleDAG. A smarter partial add with a staging area (like git)
    remains to be implemented.
`,
	Run: func(res cmds.Response, req cmds.Request) {
		n := req.Context().Node

		// if recursive, set depth to reflect so
		// opt, found := req.Option("r")
		// if r, _ := opt.(bool); found && r {
		// }

		readers, err := internal.ToReaders(req.Arguments())
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		dagnodes, err := add(n, readers)
		if err != nil {
			res.SetError(errors.New("cast error"), cmds.ErrNormal)
			return
		}

		added := make([]Object, len(req.Arguments()))
		for _, dagnode := range dagnodes {

			k, err := dagnode.Key()
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}
			added = append(added, Object{Hash: k.String(), Links: nil})
		}

		res.SetOutput(&AddOutput{added})
	},
	Marshallers: map[cmds.EncodingType]cmds.Marshaller{
		cmds.Text: func(res cmds.Response) ([]byte, error) {
			val, ok := res.Output().(*AddOutput)
			if !ok {
				return nil, errors.New("cast err")
			}
			added := val.Added
			if len(added) == 1 {
				s := fmt.Sprintf("Added object: %s\n", added[0].Hash)
				return []byte(s), nil
			}

			s := fmt.Sprintf("Added %v objects:\n", len(added))
			for _, obj := range added {
				s += fmt.Sprintf("- %s\n", obj.Hash)
			}
			return []byte(s), nil
		},
	},
	Type: &AddOutput{},
}

func add(n *core.IpfsNode, readers []io.Reader) ([]*dag.Node, error) {

	dagnodes := make([]*dag.Node, 0)

	for _, reader := range readers {
		node, err := importer.NewDagFromReader(reader)
		if err != nil {
			return nil, err
		}

		err = addNode(n, node)
		if err != nil {
			return nil, err
		}

		dagnodes = append(dagnodes, node)
	}
	return dagnodes, nil
}

func addNode(n *core.IpfsNode, node *dag.Node) error {
	err := n.DAG.AddRecursive(node) // add the file to the graph + local storage
	if err != nil {
		return err
	}

	err = n.Pinning.Pin(node, true) // ensure we keep it
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>core/commands2: Fixed 'add' output adding an empty object<commit_after>package commands

import (
	"errors"
	"fmt"
	"io"

	cmds "github.com/jbenet/go-ipfs/commands"
	core "github.com/jbenet/go-ipfs/core"
	internal "github.com/jbenet/go-ipfs/core/commands2/internal"
	importer "github.com/jbenet/go-ipfs/importer"
	dag "github.com/jbenet/go-ipfs/merkledag"
)

// Error indicating the max depth has been exceded.
var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded")

type AddOutput struct {
	Added []*Object
}

var addCmd = &cmds.Command{
	Options: []cmds.Option{
		cmds.Option{[]string{"recursive", "r"}, cmds.Bool, "Must be specified when adding directories"},
	},
	Arguments: []cmds.Argument{
		cmds.Argument{"file", cmds.ArgFile, true, true, "The path to a file to be added to IPFS"},
	},
	Description: "Add an object to ipfs.",
	Help: `Adds contents of <path> to ipfs. Use -r to add directories.
    Note that directories are added recursively, to form the ipfs
    MerkleDAG. A smarter partial add with a staging area (like git)
    remains to be implemented.
`,
	Run: func(res cmds.Response, req cmds.Request) {
		n := req.Context().Node

		// if recursive, set depth to reflect so
		// opt, found := req.Option("r")
		// if r, _ := opt.(bool); found && r {
		// }

		readers, err := internal.ToReaders(req.Arguments())
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		dagnodes, err := add(n, readers)
		if err != nil {
			res.SetError(errors.New("cast error"), cmds.ErrNormal)
			return
		}

		added := make([]*Object, 0, len(req.Arguments()))
		for _, dagnode := range dagnodes {
			object, err := getOutput(dagnode)
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}

			added = append(added, object)
		}

		res.SetOutput(&AddOutput{added})
	},
	Marshallers: map[cmds.EncodingType]cmds.Marshaller{
		cmds.Text: func(res cmds.Response) ([]byte, error) {
			val, ok := res.Output().(*AddOutput)
			if !ok {
				return nil, errors.New("cast err")
			}
			added := val.Added
			if len(added) == 1 {
				s := fmt.Sprintf("Added object: %s\n", added[0].Hash)
				return []byte(s), nil
			}

			s := fmt.Sprintf("Added %v objects:\n", len(added))
			for _, obj := range added {
				s += fmt.Sprintf("- %s\n", obj.Hash)
			}
			return []byte(s), nil
		},
	},
	Type: &AddOutput{},
}

func add(n *core.IpfsNode, readers []io.Reader) ([]*dag.Node, error) {
	dagnodes := make([]*dag.Node, 0)

	for _, reader := range readers {
		node, err := importer.NewDagFromReader(reader)
		if err != nil {
			return nil, err
		}

		err = addNode(n, node)
		if err != nil {
			return nil, err
		}

		dagnodes = append(dagnodes, node)
	}

	return dagnodes, nil
}

func addNode(n *core.IpfsNode, node *dag.Node) error {
	err := n.DAG.AddRecursive(node) // add the file to the graph + local storage
	if err != nil {
		return err
	}

	err = n.Pinning.Pin(node, true) // ensure we keep it
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package assert

import (
	"reflect"
	"runtime"
	"testing"
	"regexp"
)

// Assert is the wrapper of testing.T
type Assert struct {
	T *testing.T
}

// New is used to create a new Assert object.
func New(t *testing.T) *Assert {
	a := Assert{T: t}
	return &a
}

// Equal is used to check if exp equals to got.
func (a *Assert) Equal(message string, exp, got interface{}) {
	result := reflect.DeepEqual(exp, got)
	if !result {
		_, file, line, _ := runtime.Caller(1)
		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect equal:%s\n\t- Expect:%v\n\t- ButGot:%v\n", file, line, a.T.Name(), message, exp, got)
		a.T.FailNow()
	}
}

// NotEqual is used to check if exp is not equals to got
func (a *Assert) NotEqual(message string, exp, got interface{}) {
	result := reflect.DeepEqual(exp, got)
	if result {
		_, file, line, _ := runtime.Caller(1)
		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect not equal:%s\n\t- Expect:%v\n\t- ButGot:%v\n", file, line, a.T.Name(), message, exp, got)
		a.T.FailNow()
	}
}
//
//// Match is used to check the got is match to the regular expression of exp.
//func (a *Assert) Match(message string, exp string, got string) {
//	regex, err :=  regexp.Compile(exp)
//	if nil != err {
//		a.T.FailNow()
//	}
//
//	if !regex.MatchString(got) {
//		_, file, line, _ := runtime.Caller(1)
//		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect match:%s\n\t- Expect:%v\n\t- ButGot:%v\n", file, line, a.T.Name(), message, exp, got)
//		a.T.FailNow()
//	}
//}

// True is used to check the got be true.
func (a *Assert) True(message string, got bool) {
	result := reflect.DeepEqual(true, got)
	if !result {
		_, file, line, _ := runtime.Caller(1)
		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect true:%s\n\t- Expect:%v\n\t- ButGot:%v\n", file, line, a.T.Name(), message, false, got)
		a.T.FailNow()
	}
}

// True is used to check the got be false.
func (a *Assert) False(message string, got bool) {
	result := reflect.DeepEqual(false, got)
	if !result {
		_, file, line, _ := runtime.Caller(1)
		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect false:%s\n\t- Expect:%v\n\t- ButGot:%v\n", file, line, a.T.Name(), message, false, got)
		a.T.FailNow()
	}
}

// Panic is used to check the fn should give a panic.
func (a *Assert) Panic(message string, fn func()) {
	defer func() {
		recover()
	}()

	fn()

	_, file, line, _ := runtime.Caller(1)
	a.T.Errorf("\n%s:%d\n%s:\n\t- Expect panic:%s\n\t- Expect:Panic\n\t- ButGot:No Panic\n", file, line, a.T.Name(), message)
	a.T.FailNow()
}

// NoPanic is used to check the fn should not give a panic.
func (a *Assert) NoPanic(message string, fn func()) {
	defer func() {
		r := recover()
		_, file, line, _ := runtime.Caller(3)
		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect no panic:%s\n\t- Expect:No Panic\n\t- ButGot:Panic(%v)\n", file, line, a.T.Name(), message, r)
		a.T.FailNow()
	}()

	fn()
}

<commit_msg>解决静态质量检查工具发现的问题<commit_after>package assert

import (
	"reflect"
	"regexp"
	"runtime"
	"testing"
)

// Assert is the wrapper of testing.T
type Assert struct {
	T *testing.T
}

// New is used to create a new Assert object.
func New(t *testing.T) *Assert {
	a := Assert{T: t}
	return &a
}

// Equal is used to check if exp equals to got.
func (a *Assert) Equal(message string, exp, got interface{}) {
	result := reflect.DeepEqual(exp, got)
	if !result {
		_, file, line, _ := runtime.Caller(1)
		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect equal:%s\n\t- Expect:%v\n\t- ButGot:%v\n", file, line, a.T.Name(), message, exp, got)
		a.T.FailNow()
	}
}

// NotEqual is used to check if exp is not equals to got
func (a *Assert) NotEqual(message string, exp, got interface{}) {
	result := reflect.DeepEqual(exp, got)
	if result {
		_, file, line, _ := runtime.Caller(1)
		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect not equal:%s\n\t- Expect:%v\n\t- ButGot:%v\n", file, line, a.T.Name(), message, exp, got)
		a.T.FailNow()
	}
}

//
//// Match is used to check the got is match to the regular expression of exp.
//func (a *Assert) Match(message string, exp string, got string) {
//	regex, err :=  regexp.Compile(exp)
//	if nil != err {
//		a.T.FailNow()
//	}
//
//	if !regex.MatchString(got) {
//		_, file, line, _ := runtime.Caller(1)
//		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect match:%s\n\t- Expect:%v\n\t- ButGot:%v\n", file, line, a.T.Name(), message, exp, got)
//		a.T.FailNow()
//	}
//}

// True is used to check the got be true.
func (a *Assert) True(message string, got bool) {
	result := reflect.DeepEqual(true, got)
	if !result {
		_, file, line, _ := runtime.Caller(1)
		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect true:%s\n\t- Expect:%v\n\t- ButGot:%v\n", file, line, a.T.Name(), message, false, got)
		a.T.FailNow()
	}
}

// True is used to check the got be false.
func (a *Assert) False(message string, got bool) {
	result := reflect.DeepEqual(false, got)
	if !result {
		_, file, line, _ := runtime.Caller(1)
		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect false:%s\n\t- Expect:%v\n\t- ButGot:%v\n", file, line, a.T.Name(), message, false, got)
		a.T.FailNow()
	}
}

// Panic is used to check the fn should give a panic.
func (a *Assert) Panic(message string, fn func()) {
	defer func() {
		recover()
	}()

	fn()

	_, file, line, _ := runtime.Caller(1)
	a.T.Errorf("\n%s:%d\n%s:\n\t- Expect panic:%s\n\t- Expect:Panic\n\t- ButGot:No Panic\n", file, line, a.T.Name(), message)
	a.T.FailNow()
}

// NoPanic is used to check the fn should not give a panic.
func (a *Assert) NoPanic(message string, fn func()) {
	defer func() {
		r := recover()
		_, file, line, _ := runtime.Caller(3)
		a.T.Errorf("\n%s:%d\n%s:\n\t- Expect no panic:%s\n\t- Expect:No Panic\n\t- ButGot:Panic(%v)\n", file, line, a.T.Name(), message, r)
		a.T.FailNow()
	}()

	fn()
}
<|endoftext|>


<commit_before>package sqlconstants

import "errors"
import "strings"

const CURRENT_VENDOR = SQLITE3
const SQLITE3_FILE_URL = "throttle.db"
const SQLITE3_CONNECTION_STRING = "file:" + SQLITE3_FILE_URL
const SQLITE3_CHECK_IF_TABLE_EXISTS = "SELECT NAME FROM SQLITE_MASTER WHERE TYPE=? AND NAME=?;"
const SQLITE3_CREATE_BUCKET_SCHEMA = "CREATE TABLE BUCKETS(NAME TEXT NOT NULL UNIQUE PRIMARY KEY, VOLUME INTEGER, CAPACITY INTEGER, TIMEFRAME INTEGER, CREATED_TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UPDATED_TIMESTAMP INTEGER)"
const SQLITE3_INSERT_INTO_BUCKET = "INSERT INTO BUCKETS (NAME, VOLUME, CAPACITY, TIMEFRAME) VALUES (?, ?, ?, ?)"
const SQLITE3_UPDATE_BUCKET = "UPDATE BUCKETS SET (VOLUME,CAPACITY,TIMEFRAME, UPDATED_TIMESTAMP) VALUES (?, ?, ?, ?)"
const SQLITE3_REFRESH_BUCKET = "UPDATE BUCKETS SET VOLUME = (VOLUME - CAPACITY/(SELECT STRFTIME('%s','now') - UPDATED_TIMESTAMP), UPDATED_TIMESTAMP = SELECT STRFTIME('%s','now')"
const SQLITE3_LOAD_BUCKET = "SELECT VOLUME, CAPACITY, TIMEFRAME FROM BUCKETS WHERE NAME = ?"
const SQLITE3_DELETE_BUCKET = "DELETE BUCKET WHERE NAME = ?"
const SQLITE3_BUCKET_NAME = "BUCKETS"
const SQLITE3_GET_SCHEMA = "SELECT SQL FROM SQLITE_MASTER WHERE TYPE=? AND NAME=?"

const (
	SQLITE3_TYPE_NULL      = ""
	SQLITE3_TYPE_INTEGER   = "INTEGER"
	SQLITE3_TYPE_TEXT      = "TEXT"
	SQLITE3_TYPE_REAL      = "REAL"
	SQLITE3_TYPE_BLOB      = "BLOG"
	SQLITE3_TYPE_BOOL      = "BOOL"
	SQLITE3_TYPE_TIMESTAMP = "TIMESTAMP"
	//add postgres, plus other types here
)

const (
	SQLITE3 = iota
	POSTGRESQL
	MYSQL
	MONGODB
)

func CurrentVendor() string {
	if CURRENT_VENDOR == SQLITE3 {
		return "sqlite3"
	} else if CURRENT_VENDOR == POSTGRESQL {
		return "postgres"
	} else if CURRENT_VENDOR == MYSQL {
		return "mysql"
	} else if CURRENT_VENDOR == MONGODB {
		return "mongodb"
	}

	return ""
}

func IsSQLConstraint(constraint string) (bool, error) {
	c := strings.ToUpper(constraint)
	if CURRENT_VENDOR == SQLITE3 {
		switch c {
		case "PRIMARY":
			return true, nil
		case "DEFAULT":
			return true, nil
		case "NOT":
			return true, nil
		case "UNIQUE":
			return true, nil
		case "CHECK":
			return true, nil
		case "REFERENCES":
			return true, nil
		case "COLLATE":
			return true, nil
		default:
			return false, nil
		}

	}

	return false, errors.New("Go type no recongnized for current db vendor => " + CurrentVendor())

}

func GoType(sqlType string) (string, error) {
	if CURRENT_VENDOR == SQLITE3 {
		switch sqlType {
		case SQLITE3_TYPE_NULL:
			return "nil", nil
		case SQLITE3_TYPE_INTEGER:
			return "int", nil
		case SQLITE3_TYPE_REAL:
			return "float64", nil
		case SQLITE3_TYPE_BOOL:
			return "bool", nil
		case SQLITE3_TYPE_TEXT:
			return "string", nil
		case SQLITE3_TYPE_TIMESTAMP:
			return "time.Time", nil
		default:
			return "", nil

		}
	}

	return "", errors.New("Go type no recongnized for current db vendor => " + CurrentVendor())

}

func SQLType(goType string) (string, error) {
	if CURRENT_VENDOR == SQLITE3 {
		switch goType {
		case "nil":
			return SQLITE3_TYPE_NULL, nil
		case "int":
			return SQLITE3_TYPE_INTEGER, nil
		case "float64":
			return SQLITE3_TYPE_REAL, nil
		case "bool":
			return SQLITE3_TYPE_BOOL, nil
		case "string":
			return SQLITE3_TYPE_TEXT, nil
		case "time.Time":
			return SQLITE3_TYPE_TIMESTAMP, nil

		}
	}

	return "", errors.New("Go type no recongnized for current db vendor => " + CurrentVendor())

}
<commit_msg>Modified SQLITE3_CREATE_BUCKET_SCHEMA to have (strftime('%s','now')) and typed CREATED_TIMESTAMP TO TIMESTAMP; SQLITE3_FILL_BUCKET, SQLITE3_DROP_BUCKETS.  Added CreateStatementFunctionsToReplace to spit of list of functions to remove from create statement.<commit_after>package sqlconstants

import "errors"
import "strings"

const CURRENT_VENDOR = SQLITE3
const SQLITE3_FILE_URL = "throttle.db"
const SQLITE3_CONNECTION_STRING = "file:" + SQLITE3_FILE_URL
const SQLITE3_CHECK_IF_TABLE_EXISTS = "SELECT NAME FROM SQLITE_MASTER WHERE TYPE=? AND NAME=?;"
const SQLITE3_CREATE_BUCKET_SCHEMA = "CREATE TABLE BUCKETS(NAME TEXT NOT NULL UNIQUE PRIMARY KEY, VOLUME INTEGER DEFAULT 0, CAPACITY INTEGER, TIMEFRAME INTEGER, CREATED_TIMESTAMP TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UPDATED_TIMESTAMP INTEGER DEFAULT (strftime('%s','now')))"
const SQLITE3_INSERT_INTO_BUCKET = "INSERT INTO BUCKETS (NAME, VOLUME, CAPACITY, TIMEFRAME) VALUES (?, ?, ?, ?)"
const SQLITE3_UPDATE_BUCKET = "UPDATE BUCKETS SET (VOLUME,CAPACITY,TIMEFRAME, UPDATED_TIMESTAMP) VALUES (?, ?, ?, ?)"

//COME BACK TO LOOK HERE IF ANYTHING GOES WRONG IN THE TIME DELAY in SQLITE3_REFRESH_BUCKET
const SQLITE3_REFRESH_BUCKET = "UPDATE BUCKETS SET VOLUME = CASE WHEN CAST(ROUND(VOLUME - ((CAPACITY*1.0)/TIMEFRAME)*(STRFTIME('%s','now') - UPDATED_TIMESTAMP)) AS INT) > 0 THEN CAST(ROUND(VOLUME - ((CAPACITY*1.0)/TIMEFRAME)*(STRFTIME('%s','now') - UPDATED_TIMESTAMP)) AS INT) ELSE 0 END, UPDATED_TIMESTAMP = STRFTIME('%s','now') WHERE NAME = ?;"
const SQLITE3_LOAD_BUCKET = "SELECT VOLUME, CAPACITY, TIMEFRAME FROM BUCKETS WHERE NAME = ?"
const SQLITE3_DELETE_BUCKET = "DELETE BUCKETS WHERE NAME = ?"
const SQLITE3_SELECT_ALL_BUCKETS = "SELECT * FROM BUCKETS where NAME = ?"
const SQLITE3_BUCKET_NAME = "BUCKETS"
const SQLITE3_GET_SCHEMA = "SELECT SQL FROM SQLITE_MASTER WHERE TYPE=? AND NAME=?"
const SQLITE3_FILL_BUCKET = "UPDATE BUCKETS SET VOLUME = VOLUME + ? WHERE NAME = ?"
const SQLITE3_DROP_BUCKETS = "DROP TABLE BUCKETS"

const (
	SQLITE3_TYPE_NULL      = ""
	SQLITE3_TYPE_INTEGER   = "INTEGER"
	SQLITE3_TYPE_TEXT      = "TEXT"
	SQLITE3_TYPE_REAL      = "REAL"
	SQLITE3_TYPE_BLOB      = "BLOG"
	SQLITE3_TYPE_BOOL      = "BOOL"
	SQLITE3_TYPE_TIMESTAMP = "TIMESTAMP"
	//add postgres, plus other types here
)

const (
	SQLITE3 = iota
	POSTGRESQL
	MYSQL
	MONGODB
)

func CreateStatementFunctionsToReplace() ([]string, error) {
	if CURRENT_VENDOR == SQLITE3 {
		return []string{"(strftime('%s','now'))"}, nil
	}

	return nil, errors.New("Error: Current Vendor is not support in CreateStatementFunctionsToReplace")
}

func CurrentVendor() string {
	if CURRENT_VENDOR == SQLITE3 {
		return "sqlite3"
	} else if CURRENT_VENDOR == POSTGRESQL {
		return "postgres"
	} else if CURRENT_VENDOR == MYSQL {
		return "mysql"
	} else if CURRENT_VENDOR == MONGODB {
		return "mongodb"
	}

	return ""
}

func IsSQLConstraint(constraint string) (bool, error) {
	c := strings.ToUpper(constraint)
	if CURRENT_VENDOR == SQLITE3 {
		switch c {
		case "PRIMARY":
			return true, nil
		case "DEFAULT":
			return true, nil
		case "NOT":
			return true, nil
		case "UNIQUE":
			return true, nil
		case "CHECK":
			return true, nil
		case "REFERENCES":
			return true, nil
		case "COLLATE":
			return true, nil
		default:
			return false, nil
		}

	}

	return false, errors.New("Go type no recongnized for current db vendor => " + CurrentVendor())

}

func GoType(sqlType string) (string, error) {
	if CURRENT_VENDOR == SQLITE3 {
		switch sqlType {
		case SQLITE3_TYPE_NULL:
			return "nil", nil
		case SQLITE3_TYPE_INTEGER:
			return "int", nil
		case SQLITE3_TYPE_REAL:
			return "float64", nil
		case SQLITE3_TYPE_BOOL:
			return "bool", nil
		case SQLITE3_TYPE_TEXT:
			return "string", nil
		case SQLITE3_TYPE_TIMESTAMP:
			return "time.Time", nil
		default:
			return "", nil

		}
	}

	return "", errors.New("Go type no recongnized for current db vendor => " + CurrentVendor())

}

func SQLType(goType string) (string, error) {
	if CURRENT_VENDOR == SQLITE3 {
		switch goType {
		case "nil":
			return SQLITE3_TYPE_NULL, nil
		case "int":
			return SQLITE3_TYPE_INTEGER, nil
		case "float64":
			return SQLITE3_TYPE_REAL, nil
		case "bool":
			return SQLITE3_TYPE_BOOL, nil
		case "string":
			return SQLITE3_TYPE_TEXT, nil
		case "time.Time":
			return SQLITE3_TYPE_TIMESTAMP, nil

		}
	}

	return "", errors.New("Go type no recongnized for current db vendor => " + CurrentVendor())

}
<|endoftext|>


<commit_before>package entity

import (
    "log"
    "os"
    "bufio"
    "encoding/json"
)

func Logout() bool {
    dat, err := os.Open("entity/curUser.txt")
    check(err)
    line := bufio.NewScanner(dat)
    line.Scan()
    if len(line.Text()) == 0 {
        dat.Close()
        return false
    }
    dat.Close()
    os.Create("entity/curUser.txt")
    return true
}

func Login(username string, password string) bool {
    dat2, err2 := os.Open("entity/curUser.txt")
    check(err2)
    line2 := bufio.NewScanner(dat2)
    line2.Scan()
    if len(line2.Text()) != 0 {
        dat2.Close()
        log.Fatal("login failed. Already logged in")
        return false
    }

    var user User
    dat, err := os.Open("entity/userInfo.txt")
    check(err)
    line := bufio.NewScanner(dat)
    for line.Scan() {
        json.Unmarshal([]byte(line.Text()), &user);
        if user.Name == username && user.Passwd == password {
    	    dat.Close()

            dat, err := os.OpenFile("entity/curUser.txt", os.O_WRONLY|os.O_CREATE, 0666)
            check(err)
            dat.WriteString(username)
            dat.Close()

            return true
        }
    }
    dat.Close()
    log.Fatal("login failed. The username or password incorrect")
    return false
}

func check(e error) {
    if e != nil {
        log.Fatal(e)
    }
}
<commit_msg>little changed<commit_after>package entity

import (
    //"log"
    "os"
    "bufio"
    "encoding/json"
)

func Logout() bool {
    dat, err := os.Open("entity/curUser.txt")
    check(err)
    line := bufio.NewScanner(dat)
    line.Scan()
    if len(line.Text()) == 0 {
        dat.Close()
        return false
    }
    dat.Close()
    os.Create("entity/curUser.txt")
    return true
}

func Login(username string, password string) bool {
    dat2, err2 := os.Open("entity/curUser.txt")
    check(err2)
    line2 := bufio.NewScanner(dat2)
    line2.Scan()
    if len(line2.Text()) != 0 {
        dat2.Close()
        //log.Fatal("login failed. Already logged in")
        return false
    }

    var user User
    dat, err := os.Open("entity/userInfo.txt")
    check(err)
    line := bufio.NewScanner(dat)
    for line.Scan() {
        json.Unmarshal([]byte(line.Text()), &user);
        if user.Name == username && user.Passwd == password {
    	    dat.Close()

            dat, err := os.OpenFile("entity/curUser.txt", os.O_WRONLY|os.O_CREATE, 0666)
            check(err)
            dat.WriteString(username)
            dat.Close()

            return true
        }
    }
    dat.Close()
    //log.Fatal("login failed. The username or password incorrect")
    return false
}

func check(e error) {
    if e != nil {
        //log.Fatal(e)
    }
}
<|endoftext|>


<commit_before>package namedtuple

import "hash/fnv"

var syncHash SynchronizedHash = NewHasher(fnv.New32a())

// Empty Tuple
var NIL Tuple = Tuple{}

type TupleType struct {
	Namespace     string // Tuple Namespace
	Name          string // Tuple Name
	NamespaceHash uint32
	Hash          uint32
	versions      [][]Field
	fields        map[string]int
}

type Version struct {
	Num    uint8
	Fields []Field
}

type Field struct {
	Name     string
	Required bool
	Type     FieldType
}

// New creates a new TupleType with the given namespace and type name
func New(namespace string, name string) (t TupleType) {
	hash := syncHash.Hash([]byte(name))
	ns_hash := syncHash.Hash([]byte(namespace))
	t = TupleType{namespace, name, ns_hash, hash, make([][]Field, 0), make(map[string]int)}
	return
}

// AddVersion adds a version to the tuple type
func (t *TupleType) AddVersion(fields ...Field) {
	t.versions = append(t.versions, fields)
	for _, field := range fields {
		t.fields[field.Name] = len(t.fields)
	}
}

// Contains determines is a field exists in the TupleType
func (t *TupleType) Contains(field string) bool {
	_, exists := t.fields[field]
	return exists
}

// Offset determines the numerical offset for the given field
func (t *TupleType) Offset(field string) (offset int, exists bool) {
	offset, exists = t.fields[field]
	return
}

// NumVersions returns the number of version in the tuple type
func (t *TupleType) NumVersions() int {
	return len(t.versions)
}

// Versions returns an array of versions contained in this type
func (t *TupleType) Versions() (vers []Version) {
	vers = make([]Version, t.NumVersions())
	for i := 0; i < t.NumVersions(); i++ {
		vers[i] = Version{uint8(i + 1), t.versions[i]}
	}
	return
}

// Builder creates a new builder from the TupleType
func (t *TupleType) Builder(buffer []byte) TupleBuilder {
	return NewBuilder(*t, buffer)
}

// FieldType is the byte representation of each field type
type FieldType uint8

const (
	Uint8Field FieldType = iota
	Uint8ArrayField
	Int8Field
	Int8ArrayField
	Uint16Field
	Uint16ArrayField
	Int16Field
	Int16ArrayField
	Uint32Field
	Uint32ArrayField
	Int32Field
	Int32ArrayField
	Uint64Field
	Uint64ArrayField
	Int64Field
	Int64ArrayField
	Float32Field
	Float32ArrayField
	Float64Field
	Float64ArrayField
	TimestampField
	TimestampArrayField
	TupleField
	TupleArrayField
	StringField
	StringArrayField
	BooleanField
	BooleanArrayField
)

// TypeCode represents a field type
type TypeCode struct {
	OpCode uint8
	Size   uint8
}

// Field Type constants
var (
	NilCode                  = TypeCode{1, 0}
	BooleanCode              = TypeCode{2, 0}
	BooleanArray8Code        = TypeCode{3, 1}
	BooleanArray16Code       = TypeCode{4, 2}
	BooleanArray32Code       = TypeCode{5, 4}
	BooleanArray64Code       = TypeCode{6, 8}
	ByteCode                 = TypeCode{7, 0}
	ByteArray8Code           = TypeCode{8, 1}
	ByteArray16Code          = TypeCode{9, 2}
	ByteArray32Code          = TypeCode{10, 4}
	ByteArray64Code          = TypeCode{11, 8}
	UnsignedByteCode         = TypeCode{12, 0}
	UnsignedByteArray8Code   = TypeCode{13, 1}
	UnsignedByteArray16Code  = TypeCode{14, 2}
	UnsignedByteArray32Code  = TypeCode{15, 4}
	UnsignedByteArray64Code  = TypeCode{16, 8}
	Short8Code               = TypeCode{17, 0}
	Short16Code              = TypeCode{18, 0}
	ShortArray8Code          = TypeCode{19, 1}
	ShortArray16Code         = TypeCode{20, 2}
	ShortArray32Code         = TypeCode{21, 4}
	ShortArray64Code         = TypeCode{22, 8}
	UnsignedShort8Code       = TypeCode{23, 0}
	UnsignedShort16Code      = TypeCode{24, 0}
	UnsignedShortArray8Code  = TypeCode{25, 1}
	UnsignedShortArray16Code = TypeCode{26, 2}
	UnsignedShortArray32Code = TypeCode{27, 4}
	UnsignedShortArray64Code = TypeCode{28, 8}
	Int8Code                 = TypeCode{29, 0}
	Int16Code                = TypeCode{30, 0}
	Int32Code                = TypeCode{31, 0}
	IntArray8Code            = TypeCode{32, 1}
	IntArray16Code           = TypeCode{33, 2}
	IntArray32Code           = TypeCode{34, 4}
	IntArray64Code           = TypeCode{35, 8}
	UnsignedInt8Code         = TypeCode{36, 0}
	UnsignedInt16Code        = TypeCode{37, 0}
	UnsignedInt32Code        = TypeCode{38, 0}
	UnsignedIntArray8Code    = TypeCode{39, 1}
	UnsignedIntArray16Code   = TypeCode{40, 2}
	UnsignedIntArray32Code   = TypeCode{41, 4}
	UnsignedIntArray64Code   = TypeCode{42, 8}
	Long8Code                = TypeCode{43, 0}
	Long16Code               = TypeCode{44, 0}
	Long32Code               = TypeCode{45, 0}
	Long64Code               = TypeCode{46, 0}
	LongArray8Code           = TypeCode{47, 1}
	LongArray16Code          = TypeCode{48, 2}
	LongArray32Code          = TypeCode{49, 4}
	LongArray64Code          = TypeCode{50, 8}
	UnsignedLong8Code        = TypeCode{51, 0}
	UnsignedLong16Code       = TypeCode{52, 0}
	UnsignedLong32Code       = TypeCode{53, 0}
	UnsignedLong64Code       = TypeCode{54, 0}
	UnsignedLongArray8Code   = TypeCode{55, 1}
	UnsignedLongArray16Code  = TypeCode{56, 2}
	UnsignedLongArray32Code  = TypeCode{57, 4}
	UnsignedLongArray64Code  = TypeCode{58, 8}
	DoubleCode               = TypeCode{59, 0}
	DoubleArray8Code         = TypeCode{60, 1}
	DoubleArray16Code        = TypeCode{61, 2}
	DoubleArray32Code        = TypeCode{62, 4}
	DoubleArray64Code        = TypeCode{63, 8}
	FloatCode                = TypeCode{64, 0}
	FloatArray8Code          = TypeCode{65, 1}
	FloatArray16Code         = TypeCode{66, 2}
	FloatArray32Code         = TypeCode{67, 4}
	FloatArray64Code         = TypeCode{68, 8}
	String8Code              = TypeCode{69, 1}
	String16Code             = TypeCode{70, 2}
	String32Code             = TypeCode{71, 4}
	String64Code             = TypeCode{72, 8}
	StringArray8Code         = TypeCode{73, 1}
	StringArray16Code        = TypeCode{74, 2}
	StringArray32Code        = TypeCode{75, 4}
	StringArray64Code        = TypeCode{76, 8}
	TimestampCode            = TypeCode{77, 0}
	TimestampArray8Code      = TypeCode{78, 1}
	TimestampArray16Code     = TypeCode{79, 2}
	TimestampArray32Code     = TypeCode{80, 4}
	TimestampArray64Code     = TypeCode{81, 8}
	Tuple8Code               = TypeCode{82, 1}
	Tuple16Code              = TypeCode{83, 2}
	Tuple32Code              = TypeCode{84, 4}
	Tuple64Code              = TypeCode{85, 8}
	TupleArray8Code          = TypeCode{86, 1}
	TupleArray16Code         = TypeCode{87, 2}
	TupleArray32Code         = TypeCode{88, 4}
	TupleArray64Code         = TypeCode{89, 8}
	// FieldName            = TypeCode{90, 1}
	// VarInt               = TypeCode{91, 0}
	// UVarInt              = TypeCode{92, 0}
)

var fieldTypes = map[byte]TypeCode{
	1:  NilCode,
	2:  BooleanCode,
	3:  BooleanArray8Code,
	4:  BooleanArray16Code,
	5:  BooleanArray32Code,
	6:  BooleanArray64Code,
	7:  ByteCode,
	8:  ByteArray8Code,
	9:  ByteArray16Code,
	10: ByteArray32Code,
	11: ByteArray64Code,
	12: UnsignedByteCode,
	13: UnsignedByteArray8Code,
	14: UnsignedByteArray16Code,
	15: UnsignedByteArray32Code,
	16: UnsignedByteArray64Code,
	17: Short8Code,
	18: Short16Code,
	19: ShortArray8Code,
	20: ShortArray16Code,
	21: ShortArray32Code,
	22: ShortArray64Code,
	23: UnsignedShort8Code,
	24: UnsignedShort16Code,
	25: UnsignedShortArray8Code,
	26: UnsignedShortArray16Code,
	27: UnsignedShortArray32Code,
	28: UnsignedShortArray64Code,
	29: Int8Code,
	30: Int16Code,
	31: Int32Code,
	32: IntArray8Code,
	33: IntArray16Code,
	34: IntArray32Code,
	35: IntArray64Code,
	36: UnsignedInt8Code,
	37: UnsignedInt16Code,
	38: UnsignedInt32Code,
	39: UnsignedIntArray8Code,
	40: UnsignedIntArray16Code,
	41: UnsignedIntArray32Code,
	42: UnsignedIntArray64Code,
	43: Long8Code,
	44: Long16Code,
	45: Long32Code,
	46: Long64Code,
	47: LongArray8Code,
	48: LongArray16Code,
	49: LongArray32Code,
	50: LongArray64Code,
	51: UnsignedLong8Code,
	52: UnsignedLong16Code,
	53: UnsignedLong32Code,
	54: UnsignedLong64Code,
	55: UnsignedLongArray8Code,
	56: UnsignedLongArray16Code,
	57: UnsignedLongArray32Code,
	58: UnsignedLongArray64Code,
	59: DoubleCode,
	60: DoubleArray8Code,
	61: DoubleArray16Code,
	62: DoubleArray32Code,
	63: DoubleArray64Code,
	64: FloatCode,
	65: FloatArray8Code,
	66: FloatArray16Code,
	67: FloatArray32Code,
	68: FloatArray64Code,
	69: String8Code,
	70: String16Code,
	71: String32Code,
	72: String64Code,
	73: StringArray8Code,
	74: StringArray16Code,
	75: StringArray32Code,
	76: StringArray64Code,
	77: TimestampCode,
	78: TimestampArray8Code,
	79: TimestampArray16Code,
	80: TimestampArray32Code,
	81: TimestampArray64Code,
	82: Tuple8Code,
	83: Tuple16Code,
	84: Tuple32Code,
	85: Tuple64Code,
	86: TupleArray8Code,
	87: TupleArray16Code,
	88: TupleArray32Code,
	89: TupleArray64Code,
}
<commit_msg>Add True/False type codes<commit_after>package namedtuple

import "hash/fnv"

var syncHash SynchronizedHash = NewHasher(fnv.New32a())

// Empty Tuple
var NIL Tuple = Tuple{}

type TupleType struct {
	Namespace     string // Tuple Namespace
	Name          string // Tuple Name
	NamespaceHash uint32
	Hash          uint32
	versions      [][]Field
	fields        map[string]int
}

type Version struct {
	Num    uint8
	Fields []Field
}

type Field struct {
	Name     string
	Required bool
	Type     FieldType
}

// New creates a new TupleType with the given namespace and type name
func New(namespace string, name string) (t TupleType) {
	hash := syncHash.Hash([]byte(name))
	ns_hash := syncHash.Hash([]byte(namespace))
	t = TupleType{namespace, name, ns_hash, hash, make([][]Field, 0), make(map[string]int)}
	return
}

// AddVersion adds a version to the tuple type
func (t *TupleType) AddVersion(fields ...Field) {
	t.versions = append(t.versions, fields)
	for _, field := range fields {
		t.fields[field.Name] = len(t.fields)
	}
}

// Contains determines is a field exists in the TupleType
func (t *TupleType) Contains(field string) bool {
	_, exists := t.fields[field]
	return exists
}

// Offset determines the numerical offset for the given field
func (t *TupleType) Offset(field string) (offset int, exists bool) {
	offset, exists = t.fields[field]
	return
}

// NumVersions returns the number of version in the tuple type
func (t *TupleType) NumVersions() int {
	return len(t.versions)
}

// Versions returns an array of versions contained in this type
func (t *TupleType) Versions() (vers []Version) {
	vers = make([]Version, t.NumVersions())
	for i := 0; i < t.NumVersions(); i++ {
		vers[i] = Version{uint8(i + 1), t.versions[i]}
	}
	return
}

// Builder creates a new builder from the TupleType
func (t *TupleType) Builder(buffer []byte) TupleBuilder {
	return NewBuilder(*t, buffer)
}

// FieldType is the byte representation of each field type
type FieldType uint8

const (
	Uint8Field FieldType = iota
	Uint8ArrayField
	Int8Field
	Int8ArrayField
	Uint16Field
	Uint16ArrayField
	Int16Field
	Int16ArrayField
	Uint32Field
	Uint32ArrayField
	Int32Field
	Int32ArrayField
	Uint64Field
	Uint64ArrayField
	Int64Field
	Int64ArrayField
	Float32Field
	Float32ArrayField
	Float64Field
	Float64ArrayField
	TimestampField
	TimestampArrayField
	TupleField
	TupleArrayField
	StringField
	StringArrayField
	BooleanField
	BooleanArrayField
)

// TypeCode represents a field type
type TypeCode struct {
	OpCode uint8
	Size   uint8
}

// Field Type constants
var (
	NilCode                  = TypeCode{0, 0}
	TrueCode                 = TypeCode{1, 0}
	FalseCode                = TypeCode{2, 0}
	BooleanArray8Code        = TypeCode{3, 1}
	BooleanArray16Code       = TypeCode{4, 2}
	BooleanArray32Code       = TypeCode{5, 4}
	BooleanArray64Code       = TypeCode{6, 8}
	ByteCode                 = TypeCode{7, 0}
	ByteArray8Code           = TypeCode{8, 1}
	ByteArray16Code          = TypeCode{9, 2}
	ByteArray32Code          = TypeCode{10, 4}
	ByteArray64Code          = TypeCode{11, 8}
	UnsignedByteCode         = TypeCode{12, 0}
	UnsignedByteArray8Code   = TypeCode{13, 1}
	UnsignedByteArray16Code  = TypeCode{14, 2}
	UnsignedByteArray32Code  = TypeCode{15, 4}
	UnsignedByteArray64Code  = TypeCode{16, 8}
	Short8Code               = TypeCode{17, 0}
	Short16Code              = TypeCode{18, 0}
	ShortArray8Code          = TypeCode{19, 1}
	ShortArray16Code         = TypeCode{20, 2}
	ShortArray32Code         = TypeCode{21, 4}
	ShortArray64Code         = TypeCode{22, 8}
	UnsignedShort8Code       = TypeCode{23, 0}
	UnsignedShort16Code      = TypeCode{24, 0}
	UnsignedShortArray8Code  = TypeCode{25, 1}
	UnsignedShortArray16Code = TypeCode{26, 2}
	UnsignedShortArray32Code = TypeCode{27, 4}
	UnsignedShortArray64Code = TypeCode{28, 8}
	Int8Code                 = TypeCode{29, 0}
	Int16Code                = TypeCode{30, 0}
	Int32Code                = TypeCode{31, 0}
	IntArray8Code            = TypeCode{32, 1}
	IntArray16Code           = TypeCode{33, 2}
	IntArray32Code           = TypeCode{34, 4}
	IntArray64Code           = TypeCode{35, 8}
	UnsignedInt8Code         = TypeCode{36, 0}
	UnsignedInt16Code        = TypeCode{37, 0}
	UnsignedInt32Code        = TypeCode{38, 0}
	UnsignedIntArray8Code    = TypeCode{39, 1}
	UnsignedIntArray16Code   = TypeCode{40, 2}
	UnsignedIntArray32Code   = TypeCode{41, 4}
	UnsignedIntArray64Code   = TypeCode{42, 8}
	Long8Code                = TypeCode{43, 0}
	Long16Code               = TypeCode{44, 0}
	Long32Code               = TypeCode{45, 0}
	Long64Code               = TypeCode{46, 0}
	LongArray8Code           = TypeCode{47, 1}
	LongArray16Code          = TypeCode{48, 2}
	LongArray32Code          = TypeCode{49, 4}
	LongArray64Code          = TypeCode{50, 8}
	UnsignedLong8Code        = TypeCode{51, 0}
	UnsignedLong16Code       = TypeCode{52, 0}
	UnsignedLong32Code       = TypeCode{53, 0}
	UnsignedLong64Code       = TypeCode{54, 0}
	UnsignedLongArray8Code   = TypeCode{55, 1}
	UnsignedLongArray16Code  = TypeCode{56, 2}
	UnsignedLongArray32Code  = TypeCode{57, 4}
	UnsignedLongArray64Code  = TypeCode{58, 8}
	DoubleCode               = TypeCode{59, 0}
	DoubleArray8Code         = TypeCode{60, 1}
	DoubleArray16Code        = TypeCode{61, 2}
	DoubleArray32Code        = TypeCode{62, 4}
	DoubleArray64Code        = TypeCode{63, 8}
	FloatCode                = TypeCode{64, 0}
	FloatArray8Code          = TypeCode{65, 1}
	FloatArray16Code         = TypeCode{66, 2}
	FloatArray32Code         = TypeCode{67, 4}
	FloatArray64Code         = TypeCode{68, 8}
	String8Code              = TypeCode{69, 1}
	String16Code             = TypeCode{70, 2}
	String32Code             = TypeCode{71, 4}
	String64Code             = TypeCode{72, 8}
	StringArray8Code         = TypeCode{73, 1}
	StringArray16Code        = TypeCode{74, 2}
	StringArray32Code        = TypeCode{75, 4}
	StringArray64Code        = TypeCode{76, 8}
	TimestampCode            = TypeCode{77, 0}
	TimestampArray8Code      = TypeCode{78, 1}
	TimestampArray16Code     = TypeCode{79, 2}
	TimestampArray32Code     = TypeCode{80, 4}
	TimestampArray64Code     = TypeCode{81, 8}
	Tuple8Code               = TypeCode{82, 1}
	Tuple16Code              = TypeCode{83, 2}
	Tuple32Code              = TypeCode{84, 4}
	Tuple64Code              = TypeCode{85, 8}
	TupleArray8Code          = TypeCode{86, 1}
	TupleArray16Code         = TypeCode{87, 2}
	TupleArray32Code         = TypeCode{88, 4}
	TupleArray64Code         = TypeCode{89, 8}
	// FieldName            = TypeCode{90, 1}
	// VarInt               = TypeCode{91, 0}
	// UVarInt              = TypeCode{92, 0}
)

var fieldTypes = map[byte]TypeCode{
	0:  NilCode,
	1:  TrueCode,
	2:  FalseCode,
	3:  BooleanArray8Code,
	4:  BooleanArray16Code,
	5:  BooleanArray32Code,
	6:  BooleanArray64Code,
	7:  ByteCode,
	8:  ByteArray8Code,
	9:  ByteArray16Code,
	10: ByteArray32Code,
	11: ByteArray64Code,
	12: UnsignedByteCode,
	13: UnsignedByteArray8Code,
	14: UnsignedByteArray16Code,
	15: UnsignedByteArray32Code,
	16: UnsignedByteArray64Code,
	17: Short8Code,
	18: Short16Code,
	19: ShortArray8Code,
	20: ShortArray16Code,
	21: ShortArray32Code,
	22: ShortArray64Code,
	23: UnsignedShort8Code,
	24: UnsignedShort16Code,
	25: UnsignedShortArray8Code,
	26: UnsignedShortArray16Code,
	27: UnsignedShortArray32Code,
	28: UnsignedShortArray64Code,
	29: Int8Code,
	30: Int16Code,
	31: Int32Code,
	32: IntArray8Code,
	33: IntArray16Code,
	34: IntArray32Code,
	35: IntArray64Code,
	36: UnsignedInt8Code,
	37: UnsignedInt16Code,
	38: UnsignedInt32Code,
	39: UnsignedIntArray8Code,
	40: UnsignedIntArray16Code,
	41: UnsignedIntArray32Code,
	42: UnsignedIntArray64Code,
	43: Long8Code,
	44: Long16Code,
	45: Long32Code,
	46: Long64Code,
	47: LongArray8Code,
	48: LongArray16Code,
	49: LongArray32Code,
	50: LongArray64Code,
	51: UnsignedLong8Code,
	52: UnsignedLong16Code,
	53: UnsignedLong32Code,
	54: UnsignedLong64Code,
	55: UnsignedLongArray8Code,
	56: UnsignedLongArray16Code,
	57: UnsignedLongArray32Code,
	58: UnsignedLongArray64Code,
	59: DoubleCode,
	60: DoubleArray8Code,
	61: DoubleArray16Code,
	62: DoubleArray32Code,
	63: DoubleArray64Code,
	64: FloatCode,
	65: FloatArray8Code,
	66: FloatArray16Code,
	67: FloatArray32Code,
	68: FloatArray64Code,
	69: String8Code,
	70: String16Code,
	71: String32Code,
	72: String64Code,
	73: StringArray8Code,
	74: StringArray16Code,
	75: StringArray32Code,
	76: StringArray64Code,
	77: TimestampCode,
	78: TimestampArray8Code,
	79: TimestampArray16Code,
	80: TimestampArray32Code,
	81: TimestampArray64Code,
	82: Tuple8Code,
	83: Tuple16Code,
	84: Tuple32Code,
	85: Tuple64Code,
	86: TupleArray8Code,
	87: TupleArray16Code,
	88: TupleArray32Code,
	89: TupleArray64Code,
}
<|endoftext|>


<commit_before>/*
   Copyright The containerd Authors.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package typeurl

import (
	"encoding/json"
	"path"
	"reflect"
	"sync"

	"github.com/gogo/protobuf/proto"
	"github.com/gogo/protobuf/types"
	"github.com/pkg/errors"
)

var (
	mu       sync.Mutex
	registry = make(map[reflect.Type]string)
)

var ErrNotFound = errors.New("not found")

// Register a type with a base URL for JSON marshaling. When the MarshalAny and
// UnmarshalAny functions are called they will treat the Any type value as JSON.
// To use protocol buffers for handling the Any value the proto.Register
// function should be used instead of this function.
func Register(v interface{}, args ...string) {
	var (
		t = tryDereference(v)
		p = path.Join(args...)
	)
	mu.Lock()
	defer mu.Unlock()
	if et, ok := registry[t]; ok {
		if et != p {
			panic(errors.Errorf("type registred with alternate path %q != %q", et, p))
		}
		return
	}
	registry[t] = p
}

// TypeURL returns the type url for a registred type.
func TypeURL(v interface{}) (string, error) {
	mu.Lock()
	u, ok := registry[tryDereference(v)]
	mu.Unlock()
	if !ok {
		// fallback to the proto registry if it is a proto message
		pb, ok := v.(proto.Message)
		if !ok {
			return "", errors.Wrapf(ErrNotFound, "type %s", reflect.TypeOf(v))
		}
		return proto.MessageName(pb), nil
	}
	return u, nil
}

// Is returns true if the type of the Any is the same as v.
func Is(any *types.Any, v interface{}) bool {
	// call to check that v is a pointer
	tryDereference(v)
	url, err := TypeURL(v)
	if err != nil {
		return false
	}
	return any.TypeUrl == url
}

// MarshalAny marshals the value v into an any with the correct TypeUrl.
// If the provided object is already a proto.Any message, then it will be
// returned verbatim. If it is of type proto.Message, it will be marshaled as a
// protocol buffer. Otherwise, the object will be marshaled to json.
func MarshalAny(v interface{}) (*types.Any, error) {
	var marshal func(v interface{}) ([]byte, error)
	switch t := v.(type) {
	case *types.Any:
		// avoid reserializing the type if we have an any.
		return t, nil
	case proto.Message:
		marshal = func(v interface{}) ([]byte, error) {
			return proto.Marshal(t)
		}
	default:
		marshal = json.Marshal
	}

	url, err := TypeURL(v)
	if err != nil {
		return nil, err
	}

	data, err := marshal(v)
	if err != nil {
		return nil, err
	}
	return &types.Any{
		TypeUrl: url,
		Value:   data,
	}, nil
}

// UnmarshalAny unmarshals the any type into a concrete type.
func UnmarshalAny(any *types.Any) (interface{}, error) {
	t, err := getTypeByUrl(any.TypeUrl)
	if err != nil {
		return nil, err
	}
	v := reflect.New(t.t).Interface()
	if t.isProto {
		err = proto.Unmarshal(any.Value, v.(proto.Message))
	} else {
		err = json.Unmarshal(any.Value, v)
	}
	return v, err
}

type urlType struct {
	t       reflect.Type
	isProto bool
}

func getTypeByUrl(url string) (urlType, error) {
	for t, u := range registry {
		if u == url {
			return urlType{
				t: t,
			}, nil
		}
	}
	// fallback to proto registry
	t := proto.MessageType(url)
	if t != nil {
		return urlType{
			// get the underlying Elem because proto returns a pointer to the type
			t:       t.Elem(),
			isProto: true,
		}, nil
	}
	return urlType{}, errors.Wrapf(ErrNotFound, "type with url %s", url)
}

func tryDereference(v interface{}) reflect.Type {
	t := reflect.TypeOf(v)
	if t.Kind() == reflect.Ptr {
		// require check of pointer but dereference to register
		return t.Elem()
	}
	panic("v is not a pointer to a type")
}
<commit_msg>typeurl: allow deserialization with decomposed Any<commit_after>/*
   Copyright The containerd Authors.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package typeurl

import (
	"encoding/json"
	"path"
	"reflect"
	"sync"

	"github.com/gogo/protobuf/proto"
	"github.com/gogo/protobuf/types"
	"github.com/pkg/errors"
)

var (
	mu       sync.Mutex
	registry = make(map[reflect.Type]string)
)

var ErrNotFound = errors.New("not found")

// Register a type with a base URL for JSON marshaling. When the MarshalAny and
// UnmarshalAny functions are called they will treat the Any type value as JSON.
// To use protocol buffers for handling the Any value the proto.Register
// function should be used instead of this function.
func Register(v interface{}, args ...string) {
	var (
		t = tryDereference(v)
		p = path.Join(args...)
	)
	mu.Lock()
	defer mu.Unlock()
	if et, ok := registry[t]; ok {
		if et != p {
			panic(errors.Errorf("type registred with alternate path %q != %q", et, p))
		}
		return
	}
	registry[t] = p
}

// TypeURL returns the type url for a registred type.
func TypeURL(v interface{}) (string, error) {
	mu.Lock()
	u, ok := registry[tryDereference(v)]
	mu.Unlock()
	if !ok {
		// fallback to the proto registry if it is a proto message
		pb, ok := v.(proto.Message)
		if !ok {
			return "", errors.Wrapf(ErrNotFound, "type %s", reflect.TypeOf(v))
		}
		return proto.MessageName(pb), nil
	}
	return u, nil
}

// Is returns true if the type of the Any is the same as v.
func Is(any *types.Any, v interface{}) bool {
	// call to check that v is a pointer
	tryDereference(v)
	url, err := TypeURL(v)
	if err != nil {
		return false
	}
	return any.TypeUrl == url
}

// MarshalAny marshals the value v into an any with the correct TypeUrl.
// If the provided object is already a proto.Any message, then it will be
// returned verbatim. If it is of type proto.Message, it will be marshaled as a
// protocol buffer. Otherwise, the object will be marshaled to json.
func MarshalAny(v interface{}) (*types.Any, error) {
	var marshal func(v interface{}) ([]byte, error)
	switch t := v.(type) {
	case *types.Any:
		// avoid reserializing the type if we have an any.
		return t, nil
	case proto.Message:
		marshal = func(v interface{}) ([]byte, error) {
			return proto.Marshal(t)
		}
	default:
		marshal = json.Marshal
	}

	url, err := TypeURL(v)
	if err != nil {
		return nil, err
	}

	data, err := marshal(v)
	if err != nil {
		return nil, err
	}
	return &types.Any{
		TypeUrl: url,
		Value:   data,
	}, nil
}

// UnmarshalAny unmarshals the any type into a concrete type.
func UnmarshalAny(any *types.Any) (interface{}, error) {
	return UnmarshalByTypeURL(any.TypeUrl, any.Value)
}

func UnmarshalByTypeURL(typeURL string, value []byte) (interface{}, error) {
	t, err := getTypeByUrl(typeURL)
	if err != nil {
		return nil, err
	}
	v := reflect.New(t.t).Interface()
	if t.isProto {
		err = proto.Unmarshal(value, v.(proto.Message))
	} else {
		err = json.Unmarshal(value, v)
	}
	return v, err
}

type urlType struct {
	t       reflect.Type
	isProto bool
}

func getTypeByUrl(url string) (urlType, error) {
	for t, u := range registry {
		if u == url {
			return urlType{
				t: t,
			}, nil
		}
	}
	// fallback to proto registry
	t := proto.MessageType(url)
	if t != nil {
		return urlType{
			// get the underlying Elem because proto returns a pointer to the type
			t:       t.Elem(),
			isProto: true,
		}, nil
	}
	return urlType{}, errors.Wrapf(ErrNotFound, "type with url %s", url)
}

func tryDereference(v interface{}) reflect.Type {
	t := reflect.TypeOf(v)
	if t.Kind() == reflect.Ptr {
		// require check of pointer but dereference to register
		return t.Elem()
	}
	panic("v is not a pointer to a type")
}
<|endoftext|>


<commit_before>package smith

import (
	"bytes"
	"encoding/json"

	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	unstructured_conversion "k8s.io/apimachinery/pkg/conversion/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
)

type BundleConditionType string

// These are valid conditions of a Bundle.
const (
	BundleInProgress BundleConditionType = "InProgress"
	BundleReady      BundleConditionType = "Ready"
	BundleError      BundleConditionType = "Error"
)

type ConditionStatus string

// These are valid condition statuses. "ConditionTrue" means a resource is in the condition.
// "ConditionFalse" means a resource is not in the condition. "ConditionUnknown" means kubernetes
// can't decide if a resource is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded.
const (
	ConditionTrue    ConditionStatus = "True"
	ConditionFalse   ConditionStatus = "False"
	ConditionUnknown ConditionStatus = "Unknown"
)

const (
	SmithDomain        = "smith.atlassian.com"
	SmithResourceGroup = SmithDomain

	BundleResourcePath         = "bundles"
	BundleResourceName         = "bundle." + SmithDomain
	BundleResourceVersion      = "v1"
	BundleResourceKind         = "Bundle"
	BundleResourceGroupVersion = SmithResourceGroup + "/" + BundleResourceVersion

	BundleNameLabel = BundleResourceName + "/BundleName"

	// See docs/design/managing-resources.md
	TprFieldPathAnnotation  = SmithDomain + "/TprReadyWhenFieldPath"
	TprFieldValueAnnotation = SmithDomain + "/TprReadyWhenFieldValue"
)

var GV = schema.GroupVersion{
	Group:   SmithResourceGroup,
	Version: BundleResourceVersion,
}

var BundleGVK = GV.WithKind(BundleResourceKind)

var converter = unstructured_conversion.NewConverter(false)

func AddToScheme(scheme *runtime.Scheme) {
	scheme.AddKnownTypes(GV,
		&Bundle{},
		&BundleList{},
	)
	meta_v1.AddToGroupVersion(scheme, GV)
}

type BundleList struct {
	meta_v1.TypeMeta `json:",inline"`
	// Standard list metadata.
	meta_v1.ListMeta `json:"metadata,omitempty"`

	// Items is a list of bundles.
	Items []Bundle `json:"items"`
}

// Bundle describes a resources bundle.
type Bundle struct {
	meta_v1.TypeMeta `json:",inline"`

	// Standard object metadata
	meta_v1.ObjectMeta `json:"metadata,omitempty"`

	// Spec is the specification of the desired behavior of the Bundle.
	Spec BundleSpec `json:"spec,omitempty"`

	// Status is most recently observed status of the Bundle.
	Status BundleStatus `json:"status,omitempty"`
}

func (b *Bundle) GetCondition(conditionType BundleConditionType) (int, *BundleCondition) {
	for i, condition := range b.Status.Conditions {
		if condition.Type == conditionType {
			return i, &condition
		}
	}
	return -1, nil
}

// Updates existing Bundle condition or creates a new one. Sets LastTransitionTime to now if the
// status has changed.
// Returns true if Bundle condition has changed or has been added.
func (b *Bundle) UpdateCondition(condition *BundleCondition) bool {
	cond := *condition // copy to avoid mutating the original
	now := meta_v1.Now()
	cond.LastTransitionTime = now
	// Try to find this bundle condition.
	conditionIndex, oldCondition := b.GetCondition(cond.Type)

	if oldCondition == nil {
		// We are adding new bundle condition.
		b.Status.Conditions = append(b.Status.Conditions, cond)
		return true
	}
	// We are updating an existing condition, so we need to check if it has changed.
	if cond.Status == oldCondition.Status {
		cond.LastTransitionTime = oldCondition.LastTransitionTime
	}

	isEqual := cond.Status == oldCondition.Status &&
		cond.Reason == oldCondition.Reason &&
		cond.Message == oldCondition.Message &&
		cond.LastTransitionTime.Equal(oldCondition.LastTransitionTime)

	if !isEqual {
		cond.LastUpdateTime = now
	}

	b.Status.Conditions[conditionIndex] = cond
	// Return true if one of the fields have changed.
	return !isEqual
}

type BundleSpec struct {
	Resources []Resource `json:"resources"`
}

// BundleCondition describes the state of a bundle at a certain point.
type BundleCondition struct {
	// Type of Bundle condition.
	Type BundleConditionType `json:"type"`
	// Status of the condition.
	Status ConditionStatus `json:"status"`
	// The last time this condition was updated.
	LastUpdateTime meta_v1.Time `json:"lastUpdateTime,omitempty"`
	// Last time the condition transitioned from one status to another.
	LastTransitionTime meta_v1.Time `json:"lastTransitionTime,omitempty"`
	// The reason for the condition's last transition.
	Reason string `json:"reason,omitempty"`
	// A human readable message indicating details about the transition.
	Message string `json:"message,omitempty"`
}

type BundleStatus struct {
	// Represents the latest available observations of a Bundle's current state.
	Conditions []BundleCondition `json:"conditions,omitempty"`
}

func (bs *BundleStatus) ShortString() string {
	first := true
	var buf bytes.Buffer
	buf.WriteByte('[')
	for _, cond := range bs.Conditions {
		if first {
			first = false
		} else {
			buf.WriteByte('|')
		}
		buf.WriteString(string(cond.Type))
		buf.WriteByte(' ')
		buf.WriteString(string(cond.Status))
		if cond.Reason != "" {
			buf.WriteByte(' ')
			buf.WriteByte('"')
			buf.WriteString(cond.Reason)
			buf.WriteByte('"')
		}
	}
	buf.WriteByte(']')
	return buf.String()
}

// ResourceName is a reference to another Resource in the same bundle.
type ResourceName string

type Resource struct {
	// Name of the resource for references.
	Name ResourceName `json:"name"`

	// Explicit dependencies.
	DependsOn []ResourceName `json:"dependsOn,omitempty"`

	Spec runtime.Object `json:"spec"`
}

// ToUnstructured returns Spec field as an Unstructured object.
// It makes a copy if it is an Unstructured already.
func (r *Resource) ToUnstructured(copy DeepCopy) (*unstructured.Unstructured, error) {
	if _, ok := r.Spec.(*unstructured.Unstructured); ok {
		uCopy, err := copy(r.Spec)
		if err != nil {
			return nil, err
		}
		return uCopy.(*unstructured.Unstructured), nil
	}
	u := &unstructured.Unstructured{
		Object: make(map[string]interface{}),
	}
	err := converter.ToUnstructured(r.Spec, &u.Object)
	if err != nil {
		return nil, err
	}
	return u, nil
}

func (r *Resource) UnmarshalJSON(data []byte) error {
	type resource struct {
		Name      ResourceName              `json:"name"`
		DependsOn []ResourceName            `json:"dependsOn"`
		Spec      unstructured.Unstructured `json:"spec"`
	}
	var res resource
	err := json.Unmarshal(data, &res)
	if err != nil {
		return err
	}
	r.Name = res.Name
	r.DependsOn = res.DependsOn
	r.Spec = &res.Spec
	return nil
}
<commit_msg>Add message to condition string<commit_after>package smith

import (
	"bytes"
	"encoding/json"

	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	unstructured_conversion "k8s.io/apimachinery/pkg/conversion/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
)

type BundleConditionType string

// These are valid conditions of a Bundle.
const (
	BundleInProgress BundleConditionType = "InProgress"
	BundleReady      BundleConditionType = "Ready"
	BundleError      BundleConditionType = "Error"
)

type ConditionStatus string

// These are valid condition statuses. "ConditionTrue" means a resource is in the condition.
// "ConditionFalse" means a resource is not in the condition. "ConditionUnknown" means kubernetes
// can't decide if a resource is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded.
const (
	ConditionTrue    ConditionStatus = "True"
	ConditionFalse   ConditionStatus = "False"
	ConditionUnknown ConditionStatus = "Unknown"
)

const (
	SmithDomain        = "smith.atlassian.com"
	SmithResourceGroup = SmithDomain

	BundleResourcePath         = "bundles"
	BundleResourceName         = "bundle." + SmithDomain
	BundleResourceVersion      = "v1"
	BundleResourceKind         = "Bundle"
	BundleResourceGroupVersion = SmithResourceGroup + "/" + BundleResourceVersion

	BundleNameLabel = BundleResourceName + "/BundleName"

	// See docs/design/managing-resources.md
	TprFieldPathAnnotation  = SmithDomain + "/TprReadyWhenFieldPath"
	TprFieldValueAnnotation = SmithDomain + "/TprReadyWhenFieldValue"
)

var GV = schema.GroupVersion{
	Group:   SmithResourceGroup,
	Version: BundleResourceVersion,
}

var BundleGVK = GV.WithKind(BundleResourceKind)

var converter = unstructured_conversion.NewConverter(false)

func AddToScheme(scheme *runtime.Scheme) {
	scheme.AddKnownTypes(GV,
		&Bundle{},
		&BundleList{},
	)
	meta_v1.AddToGroupVersion(scheme, GV)
}

type BundleList struct {
	meta_v1.TypeMeta `json:",inline"`
	// Standard list metadata.
	meta_v1.ListMeta `json:"metadata,omitempty"`

	// Items is a list of bundles.
	Items []Bundle `json:"items"`
}

// Bundle describes a resources bundle.
type Bundle struct {
	meta_v1.TypeMeta `json:",inline"`

	// Standard object metadata
	meta_v1.ObjectMeta `json:"metadata,omitempty"`

	// Spec is the specification of the desired behavior of the Bundle.
	Spec BundleSpec `json:"spec,omitempty"`

	// Status is most recently observed status of the Bundle.
	Status BundleStatus `json:"status,omitempty"`
}

func (b *Bundle) GetCondition(conditionType BundleConditionType) (int, *BundleCondition) {
	for i, condition := range b.Status.Conditions {
		if condition.Type == conditionType {
			return i, &condition
		}
	}
	return -1, nil
}

// Updates existing Bundle condition or creates a new one. Sets LastTransitionTime to now if the
// status has changed.
// Returns true if Bundle condition has changed or has been added.
func (b *Bundle) UpdateCondition(condition *BundleCondition) bool {
	cond := *condition // copy to avoid mutating the original
	now := meta_v1.Now()
	cond.LastTransitionTime = now
	// Try to find this bundle condition.
	conditionIndex, oldCondition := b.GetCondition(cond.Type)

	if oldCondition == nil {
		// We are adding new bundle condition.
		b.Status.Conditions = append(b.Status.Conditions, cond)
		return true
	}
	// We are updating an existing condition, so we need to check if it has changed.
	if cond.Status == oldCondition.Status {
		cond.LastTransitionTime = oldCondition.LastTransitionTime
	}

	isEqual := cond.Status == oldCondition.Status &&
		cond.Reason == oldCondition.Reason &&
		cond.Message == oldCondition.Message &&
		cond.LastTransitionTime.Equal(oldCondition.LastTransitionTime)

	if !isEqual {
		cond.LastUpdateTime = now
	}

	b.Status.Conditions[conditionIndex] = cond
	// Return true if one of the fields have changed.
	return !isEqual
}

type BundleSpec struct {
	Resources []Resource `json:"resources"`
}

// BundleCondition describes the state of a bundle at a certain point.
type BundleCondition struct {
	// Type of Bundle condition.
	Type BundleConditionType `json:"type"`
	// Status of the condition.
	Status ConditionStatus `json:"status"`
	// The last time this condition was updated.
	LastUpdateTime meta_v1.Time `json:"lastUpdateTime,omitempty"`
	// Last time the condition transitioned from one status to another.
	LastTransitionTime meta_v1.Time `json:"lastTransitionTime,omitempty"`
	// The reason for the condition's last transition.
	Reason string `json:"reason,omitempty"`
	// A human readable message indicating details about the transition.
	Message string `json:"message,omitempty"`
}

type BundleStatus struct {
	// Represents the latest available observations of a Bundle's current state.
	Conditions []BundleCondition `json:"conditions,omitempty"`
}

func (bs *BundleStatus) ShortString() string {
	first := true
	var buf bytes.Buffer
	buf.WriteByte('[')
	for _, cond := range bs.Conditions {
		if first {
			first = false
		} else {
			buf.WriteByte('|')
		}
		buf.WriteString(string(cond.Type))
		buf.WriteByte(' ')
		buf.WriteString(string(cond.Status))
		if cond.Reason != "" {
			buf.WriteByte(' ')
			buf.WriteByte('"')
			buf.WriteString(cond.Reason)
			buf.WriteByte('"')
		}
		if cond.Message != "" {
			buf.WriteByte(' ')
			buf.WriteByte('"')
			buf.WriteString(cond.Message)
			buf.WriteByte('"')
		}
	}
	buf.WriteByte(']')
	return buf.String()
}

// ResourceName is a reference to another Resource in the same bundle.
type ResourceName string

type Resource struct {
	// Name of the resource for references.
	Name ResourceName `json:"name"`

	// Explicit dependencies.
	DependsOn []ResourceName `json:"dependsOn,omitempty"`

	Spec runtime.Object `json:"spec"`
}

// ToUnstructured returns Spec field as an Unstructured object.
// It makes a copy if it is an Unstructured already.
func (r *Resource) ToUnstructured(copy DeepCopy) (*unstructured.Unstructured, error) {
	if _, ok := r.Spec.(*unstructured.Unstructured); ok {
		uCopy, err := copy(r.Spec)
		if err != nil {
			return nil, err
		}
		return uCopy.(*unstructured.Unstructured), nil
	}
	u := &unstructured.Unstructured{
		Object: make(map[string]interface{}),
	}
	err := converter.ToUnstructured(r.Spec, &u.Object)
	if err != nil {
		return nil, err
	}
	return u, nil
}

func (r *Resource) UnmarshalJSON(data []byte) error {
	type resource struct {
		Name      ResourceName              `json:"name"`
		DependsOn []ResourceName            `json:"dependsOn"`
		Spec      unstructured.Unstructured `json:"spec"`
	}
	var res resource
	err := json.Unmarshal(data, &res)
	if err != nil {
		return err
	}
	r.Name = res.Name
	r.DependsOn = res.DependsOn
	r.Spec = &res.Spec
	return nil
}
<|endoftext|>


<commit_before>package sypexgeo

import (
	"encoding/binary"
	"errors"
	"math"
	"strconv"
	"strings"
)

func readUint32(bs []byte, offset int) uint32 { // faster than `binary.BigEndian.Uint32`
	return uint32(bs[offset])<<24 + uint32(bs[offset+1])<<16 + uint32(bs[offset+2])<<8 + uint32(bs[offset+3])
}
func readUint16(bs []byte, offset int) uint16 {
	return uint16(bs[offset])<<8 + uint16(bs[offset+1])
}
func readUint32L(bs []byte, offset int) uint32 {
	return uint32(bs[offset+3])<<24 + uint32(bs[offset+2])<<16 + uint32(bs[offset+1])<<8 + uint32(bs[offset])
}
func readUint16L(bs []byte, offset int) uint16 {
	return uint16(bs[offset+1])<<8 + uint16(bs[offset])
}
func readN32L(bs []byte, offset int, coma int) float32 {
	return float32(binary.LittleEndian.Uint32(bs[offset:offset+4])) / float32(math.Pow10(coma))
}
func readN16L(bs []byte, offset int, coma int) float32 {
	return float32(binary.LittleEndian.Uint16(bs[offset:offset+2])) / float32(math.Pow10(coma))
}
func readString(bs []byte, offset int) string { // faster than `binary.BigEndian.Uint32`
	i := offset
	for {
		i++
		if bs[i] == 0 || i >= len(bs) {
			break
		}
	}
	return string(bs[offset:i])
}

func fullUint32(bs []byte) (r []uint32) {
	r = make([]uint32, len(bs)/4)
	for i := 0; i < len(bs); i += 4 {
		r[i/4] = readUint32(bs, i)
	}
	return
}
func sliceUint32(bs []byte, offset, getLen uint32) uint32 {
	if getLen > 4 {
		panic("sliceUint32: getLen > 4")
	}
	return readUint32(append(make([]byte, 4-getLen), bs[offset:offset+getLen]...), 0)
}
func sliceUint32L(bs []byte, offset, getLen int) uint32 {
	if getLen > 4 {
		panic("sliceUint32: getLen > 4")
	}
	return readUint32L(append(append([]byte{}, bs[offset:offset+getLen]...), make([]byte, 4-getLen)...), 0)
}

func getIPByte(IP string, n byte) (byte, error) {
	sIP := strings.Split(IP, ".")
	if len(sIP) < 4 {
		return 0, errors.New("IP out of range")
	}
	b, err := strconv.ParseUint(sIP[n], 10, 8)
	if err != nil {
		return 0, err
	}
	return byte(b), nil
}

// Convert string IP to int64
func ipToN(IP string) int64 {
	b0, _ := getIPByte(IP, 0)
	b1, _ := getIPByte(IP, 1)
	b2, _ := getIPByte(IP, 2)
	b3, _ := getIPByte(IP, 3)
	var sum int64

	sum += int64(b0) << 24
	sum += int64(b1) << 16
	sum += int64(b2) << 8
	sum += int64(b3)
	return sum
}

func max32(a uint32, b uint32) (c uint32) {
	c = a
	if b > a {
		c = b
	}
	return
}

func min32(a uint32, b uint32) (c uint32) {
	c = a
	if b < a {
		c = b
	}
	return
}
<commit_msg>fix incorrect processing of negative latitude and longitude<commit_after>package sypexgeo

import (
	"encoding/binary"
	"errors"
	"math"
	"strconv"
	"strings"
)

func readUint32(bs []byte, offset int) uint32 { // faster than `binary.BigEndian.Uint32`
	return uint32(bs[offset])<<24 + uint32(bs[offset+1])<<16 + uint32(bs[offset+2])<<8 + uint32(bs[offset+3])
}
func readUint16(bs []byte, offset int) uint16 {
	return uint16(bs[offset])<<8 + uint16(bs[offset+1])
}
func readUint32L(bs []byte, offset int) uint32 {
	return uint32(bs[offset+3])<<24 + uint32(bs[offset+2])<<16 + uint32(bs[offset+1])<<8 + uint32(bs[offset])
}
func readUint16L(bs []byte, offset int) uint16 {
	return uint16(bs[offset+1])<<8 + uint16(bs[offset])
}
func readN32L(bs []byte, offset int, coma int) float32 {
	return float32(int32(binary.LittleEndian.Uint32(bs[offset:offset+4]))) / float32(math.Pow10(coma))
}
func readN16L(bs []byte, offset int, coma int) float32 {
	return float32(int16(binary.LittleEndian.Uint16(bs[offset:offset+2]))) / float32(math.Pow10(coma))
}
func readString(bs []byte, offset int) string { // faster than `binary.BigEndian.Uint32`
	i := offset
	for {
		i++
		if bs[i] == 0 || i >= len(bs) {
			break
		}
	}
	return string(bs[offset:i])
}

func fullUint32(bs []byte) (r []uint32) {
	r = make([]uint32, len(bs)/4)
	for i := 0; i < len(bs); i += 4 {
		r[i/4] = readUint32(bs, i)
	}
	return
}
func sliceUint32(bs []byte, offset, getLen uint32) uint32 {
	if getLen > 4 {
		panic("sliceUint32: getLen > 4")
	}
	return readUint32(append(make([]byte, 4-getLen), bs[offset:offset+getLen]...), 0)
}
func sliceUint32L(bs []byte, offset, getLen int) uint32 {
	if getLen > 4 {
		panic("sliceUint32: getLen > 4")
	}
	return readUint32L(append(append([]byte{}, bs[offset:offset+getLen]...), make([]byte, 4-getLen)...), 0)
}

func getIPByte(IP string, n byte) (byte, error) {
	sIP := strings.Split(IP, ".")
	if len(sIP) < 4 {
		return 0, errors.New("IP out of range")
	}
	b, err := strconv.ParseUint(sIP[n], 10, 8)
	if err != nil {
		return 0, err
	}
	return byte(b), nil
}

// Convert string IP to int64
func ipToN(IP string) int64 {
	b0, _ := getIPByte(IP, 0)
	b1, _ := getIPByte(IP, 1)
	b2, _ := getIPByte(IP, 2)
	b3, _ := getIPByte(IP, 3)
	var sum int64

	sum += int64(b0) << 24
	sum += int64(b1) << 16
	sum += int64(b2) << 8
	sum += int64(b3)
	return sum
}

func max32(a uint32, b uint32) (c uint32) {
	c = a
	if b > a {
		c = b
	}
	return
}

func min32(a uint32, b uint32) (c uint32) {
	c = a
	if b < a {
		c = b
	}
	return
}
<|endoftext|>