<commit_before>package aws

import (
	"fmt"
	"log"
	"strings"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/sns"
	"time"
)

const awsSNSPendingConfirmationMessage = "pending confirmation"
const awsSNSPendingConfirmationMessageWithoutSpaces = "pendingconfirmation"

func resourceAwsSnsTopicSubscription() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsSnsTopicSubscriptionCreate,
		Read:   resourceAwsSnsTopicSubscriptionRead,
		Update: resourceAwsSnsTopicSubscriptionUpdate,
		Delete: resourceAwsSnsTopicSubscriptionDelete,

		Schema: map[string]*schema.Schema{
			"protocol": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: false,
				ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
					value := v.(string)
					forbidden := []string{"email", "sms"}
					for _, f := range forbidden {
						if strings.Contains(value, f) {
							errors = append(
								errors,
								fmt.Errorf("Unsupported protocol (%s) for SNS Topic", value),
							)
						}
					}
					return
				},
			},
			"endpoint": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"endpoint_auto_confirms": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"confirmation_timeout_in_minutes": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  1,
			},
			"topic_arn": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"delivery_policy": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"raw_message_delivery": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"arn": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func resourceAwsSnsTopicSubscriptionCreate(d *schema.ResourceData, meta interface{}) error {
	snsconn := meta.(*AWSClient).snsconn

	output, err := subscribeToSNSTopic(d, snsconn)

	if err != nil {
		return err
	}

	if subscriptionHasPendingConfirmation(output.SubscriptionArn) {
		log.Printf("[WARN] Invalid SNS Subscription, received a \"%s\" ARN", awsSNSPendingConfirmationMessage)
		return nil
	}

	log.Printf("New subscription ARN: %s", *output.SubscriptionArn)
	d.SetId(*output.SubscriptionArn)

	// Write the ARN to the 'arn' field for export
	d.Set("arn", *output.SubscriptionArn)

	return resourceAwsSnsTopicSubscriptionUpdate(d, meta)
}

func resourceAwsSnsTopicSubscriptionUpdate(d *schema.ResourceData, meta interface{}) error {
	snsconn := meta.(*AWSClient).snsconn

	// If any changes happened, un-subscribe and re-subscribe
	if d.HasChange("protocol") || d.HasChange("endpoint") || d.HasChange("topic_arn") {
		log.Printf("[DEBUG] Updating subscription %s", d.Id())
		// Unsubscribe
		_, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{
			SubscriptionArn: aws.String(d.Id()),
		})

		if err != nil {
			return fmt.Errorf("Error unsubscribing from SNS topic: %s", err)
		}

		// Re-subscribe and set id
		output, err := subscribeToSNSTopic(d, snsconn)
		d.SetId(*output.SubscriptionArn)
		d.Set("arn", *output.SubscriptionArn)
	}

	if d.HasChange("raw_message_delivery") {
		_, n := d.GetChange("raw_message_delivery")

		attrValue := "false"

		if n.(bool) {
			attrValue = "true"
		}

		req := &sns.SetSubscriptionAttributesInput{
			SubscriptionArn: aws.String(d.Id()),
			AttributeName:   aws.String("RawMessageDelivery"),
			AttributeValue:  aws.String(attrValue),
		}
		_, err := snsconn.SetSubscriptionAttributes(req)

		if err != nil {
			return fmt.Errorf("Unable to set raw message delivery attribute on subscription")
		}
	}

	return resourceAwsSnsTopicSubscriptionRead(d, meta)
}

func resourceAwsSnsTopicSubscriptionRead(d *schema.ResourceData, meta interface{}) error {
	snsconn := meta.(*AWSClient).snsconn

	log.Printf("[DEBUG] Loading subscription %s", d.Id())

	attributeOutput, err := snsconn.GetSubscriptionAttributes(&sns.GetSubscriptionAttributesInput{
		SubscriptionArn: aws.String(d.Id()),
	})
	if err != nil {
		return err
	}

	if attributeOutput.Attributes != nil && len(attributeOutput.Attributes) > 0 {
		attrHash := attributeOutput.Attributes
		log.Printf("[DEBUG] raw message delivery: %s", *attrHash["RawMessageDelivery"])
		if *attrHash["RawMessageDelivery"] == "true" {
			d.Set("raw_message_delivery", true)
		} else {
			d.Set("raw_message_delivery", false)
		}
	}

	return nil
}

func resourceAwsSnsTopicSubscriptionDelete(d *schema.ResourceData, meta interface{}) error {
	snsconn := meta.(*AWSClient).snsconn

	log.Printf("[DEBUG] SNS delete topic subscription: %s", d.Id())
	_, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{
		SubscriptionArn: aws.String(d.Id()),
	})
	if err != nil {
		return err
	}
	return nil
}

func subscribeToSNSTopic(d *schema.ResourceData, snsconn *sns.SNS) (output *sns.SubscribeOutput, err error) {
	protocol := d.Get("protocol").(string)
	endpoint := d.Get("endpoint").(string)
	topic_arn := d.Get("topic_arn").(string)
	endpoint_auto_confirms := d.Get("endpoint_auto_confirms").(bool)
	confirmation_timeout_in_minutes := d.Get("confirmation_timeout_in_minutes").(int)

	if strings.Contains(protocol, "http") && !endpoint_auto_confirms {
		return nil, fmt.Errorf("Protocol http/https is only supported for endpoints which auto confirms!")
	}

	log.Printf("[DEBUG] SNS create topic subscription: %s (%s) @ '%s'", endpoint, protocol, topic_arn)

	req := &sns.SubscribeInput{
		Protocol: aws.String(protocol),
		Endpoint: aws.String(endpoint),
		TopicArn: aws.String(topic_arn),
	}

	output, err = snsconn.Subscribe(req)
	if err != nil {
		return nil, fmt.Errorf("Error creating SNS topic: %s", err)
	}

	log.Printf("[DEBUG] Finished subscribing to topic %s with subscription arn %s", topic_arn, *output.SubscriptionArn)

	if strings.Contains(protocol, "http") && subscriptionHasPendingConfirmation(output.SubscriptionArn) {

		log.Printf("[DEBUG] SNS create topic subscription is pending so fetching the subscription list for topic : %s (%s) @ '%s'", endpoint, protocol, topic_arn)

		err = resource.Retry(time.Duration(int(time.Minute)*confirmation_timeout_in_minutes), func() error {

			subscription, err := findSubscriptionByNonID(d, snsconn)

			if subscription != nil {
				output.SubscriptionArn = subscription.SubscriptionArn
				return nil
			}

			if err != nil {
				return fmt.Errorf("Error fetching subscriptions for SNS topic %s: %s", topic_arn, err)
			}

			return fmt.Errorf("Endpoint (%s) did not autoconfirm the subscription for topic %s", endpoint, topic_arn)
		})

		if err != nil {
			return nil, err
		}
	}

	log.Printf("[DEBUG] Created new subscription! %s", *output.SubscriptionArn)
	return output, nil
}

// finds a subscription using protocol, endpoint and topic_arn (which is a key in sns subscription)
func findSubscriptionByNonID(d *schema.ResourceData, snsconn *sns.SNS) (*sns.Subscription, error) {
	protocol := d.Get("protocol").(string)
	endpoint := d.Get("endpoint").(string)
	topic_arn := d.Get("topic_arn").(string)

	req := &sns.ListSubscriptionsByTopicInput{
		TopicArn: aws.String(topic_arn),
	}

	for {

		res, err := snsconn.ListSubscriptionsByTopic(req)

		if err != nil {
			return nil, fmt.Errorf("Error fetching subscripitions for topic %s : %s", topic_arn, err)
		}

		for _, subscription := range res.Subscriptions {
			log.Printf("[DEBUG] check subscription with EndPoint %s, Protocol %s,  topicARN %s and SubscriptionARN %s", *subscription.Endpoint, *subscription.Protocol, *subscription.TopicArn, *subscription.SubscriptionArn)
			if *subscription.Endpoint == endpoint && *subscription.Protocol == protocol && *subscription.TopicArn == topic_arn && !subscriptionHasPendingConfirmation(subscription.SubscriptionArn) {
				return subscription, nil
			}
		}

		// if there are more than 100 subscriptions then go to the next 100 otherwise return nil
		if res.NextToken != nil {
			req.NextToken = res.NextToken
		} else {
			return nil, nil
		}
	}
}

// returns true if arn is nil or has both pending and confirmation words in the arn
func subscriptionHasPendingConfirmation(arn *string) bool {
	if arn != nil && !strings.Contains(strings.Replace(strings.ToLower(*arn), " ", "", -1), awsSNSPendingConfirmationMessageWithoutSpaces) {
		return false
	}

	return true
}
<commit_msg>provider/aws: Fix int overflow on 386 builds<commit_after>package aws

import (
	"fmt"
	"log"
	"strings"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"

	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/sns"
)

const awsSNSPendingConfirmationMessage = "pending confirmation"
const awsSNSPendingConfirmationMessageWithoutSpaces = "pendingconfirmation"

func resourceAwsSnsTopicSubscription() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsSnsTopicSubscriptionCreate,
		Read:   resourceAwsSnsTopicSubscriptionRead,
		Update: resourceAwsSnsTopicSubscriptionUpdate,
		Delete: resourceAwsSnsTopicSubscriptionDelete,

		Schema: map[string]*schema.Schema{
			"protocol": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: false,
				ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
					value := v.(string)
					forbidden := []string{"email", "sms"}
					for _, f := range forbidden {
						if strings.Contains(value, f) {
							errors = append(
								errors,
								fmt.Errorf("Unsupported protocol (%s) for SNS Topic", value),
							)
						}
					}
					return
				},
			},
			"endpoint": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"endpoint_auto_confirms": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"confirmation_timeout_in_minutes": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  1,
			},
			"topic_arn": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"delivery_policy": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"raw_message_delivery": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"arn": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func resourceAwsSnsTopicSubscriptionCreate(d *schema.ResourceData, meta interface{}) error {
	snsconn := meta.(*AWSClient).snsconn

	output, err := subscribeToSNSTopic(d, snsconn)

	if err != nil {
		return err
	}

	if subscriptionHasPendingConfirmation(output.SubscriptionArn) {
		log.Printf("[WARN] Invalid SNS Subscription, received a \"%s\" ARN", awsSNSPendingConfirmationMessage)
		return nil
	}

	log.Printf("New subscription ARN: %s", *output.SubscriptionArn)
	d.SetId(*output.SubscriptionArn)

	// Write the ARN to the 'arn' field for export
	d.Set("arn", *output.SubscriptionArn)

	return resourceAwsSnsTopicSubscriptionUpdate(d, meta)
}

func resourceAwsSnsTopicSubscriptionUpdate(d *schema.ResourceData, meta interface{}) error {
	snsconn := meta.(*AWSClient).snsconn

	// If any changes happened, un-subscribe and re-subscribe
	if d.HasChange("protocol") || d.HasChange("endpoint") || d.HasChange("topic_arn") {
		log.Printf("[DEBUG] Updating subscription %s", d.Id())
		// Unsubscribe
		_, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{
			SubscriptionArn: aws.String(d.Id()),
		})

		if err != nil {
			return fmt.Errorf("Error unsubscribing from SNS topic: %s", err)
		}

		// Re-subscribe and set id
		output, err := subscribeToSNSTopic(d, snsconn)
		d.SetId(*output.SubscriptionArn)
		d.Set("arn", *output.SubscriptionArn)
	}

	if d.HasChange("raw_message_delivery") {
		_, n := d.GetChange("raw_message_delivery")

		attrValue := "false"

		if n.(bool) {
			attrValue = "true"
		}

		req := &sns.SetSubscriptionAttributesInput{
			SubscriptionArn: aws.String(d.Id()),
			AttributeName:   aws.String("RawMessageDelivery"),
			AttributeValue:  aws.String(attrValue),
		}
		_, err := snsconn.SetSubscriptionAttributes(req)

		if err != nil {
			return fmt.Errorf("Unable to set raw message delivery attribute on subscription")
		}
	}

	return resourceAwsSnsTopicSubscriptionRead(d, meta)
}

func resourceAwsSnsTopicSubscriptionRead(d *schema.ResourceData, meta interface{}) error {
	snsconn := meta.(*AWSClient).snsconn

	log.Printf("[DEBUG] Loading subscription %s", d.Id())

	attributeOutput, err := snsconn.GetSubscriptionAttributes(&sns.GetSubscriptionAttributesInput{
		SubscriptionArn: aws.String(d.Id()),
	})
	if err != nil {
		return err
	}

	if attributeOutput.Attributes != nil && len(attributeOutput.Attributes) > 0 {
		attrHash := attributeOutput.Attributes
		log.Printf("[DEBUG] raw message delivery: %s", *attrHash["RawMessageDelivery"])
		if *attrHash["RawMessageDelivery"] == "true" {
			d.Set("raw_message_delivery", true)
		} else {
			d.Set("raw_message_delivery", false)
		}
	}

	return nil
}

func resourceAwsSnsTopicSubscriptionDelete(d *schema.ResourceData, meta interface{}) error {
	snsconn := meta.(*AWSClient).snsconn

	log.Printf("[DEBUG] SNS delete topic subscription: %s", d.Id())
	_, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{
		SubscriptionArn: aws.String(d.Id()),
	})
	if err != nil {
		return err
	}
	return nil
}

func subscribeToSNSTopic(d *schema.ResourceData, snsconn *sns.SNS) (output *sns.SubscribeOutput, err error) {
	protocol := d.Get("protocol").(string)
	endpoint := d.Get("endpoint").(string)
	topic_arn := d.Get("topic_arn").(string)
	endpoint_auto_confirms := d.Get("endpoint_auto_confirms").(bool)
	confirmation_timeout_in_minutes := d.Get("confirmation_timeout_in_minutes").(int)

	if strings.Contains(protocol, "http") && !endpoint_auto_confirms {
		return nil, fmt.Errorf("Protocol http/https is only supported for endpoints which auto confirms!")
	}

	log.Printf("[DEBUG] SNS create topic subscription: %s (%s) @ '%s'", endpoint, protocol, topic_arn)

	req := &sns.SubscribeInput{
		Protocol: aws.String(protocol),
		Endpoint: aws.String(endpoint),
		TopicArn: aws.String(topic_arn),
	}

	output, err = snsconn.Subscribe(req)
	if err != nil {
		return nil, fmt.Errorf("Error creating SNS topic: %s", err)
	}

	log.Printf("[DEBUG] Finished subscribing to topic %s with subscription arn %s", topic_arn, *output.SubscriptionArn)

	if strings.Contains(protocol, "http") && subscriptionHasPendingConfirmation(output.SubscriptionArn) {

		log.Printf("[DEBUG] SNS create topic subscription is pending so fetching the subscription list for topic : %s (%s) @ '%s'", endpoint, protocol, topic_arn)

		err = resource.Retry(time.Duration(confirmation_timeout_in_minutes)*time.Minute, func() error {

			subscription, err := findSubscriptionByNonID(d, snsconn)

			if subscription != nil {
				output.SubscriptionArn = subscription.SubscriptionArn
				return nil
			}

			if err != nil {
				return fmt.Errorf("Error fetching subscriptions for SNS topic %s: %s", topic_arn, err)
			}

			return fmt.Errorf("Endpoint (%s) did not autoconfirm the subscription for topic %s", endpoint, topic_arn)
		})

		if err != nil {
			return nil, err
		}
	}

	log.Printf("[DEBUG] Created new subscription! %s", *output.SubscriptionArn)
	return output, nil
}

// finds a subscription using protocol, endpoint and topic_arn (which is a key in sns subscription)
func findSubscriptionByNonID(d *schema.ResourceData, snsconn *sns.SNS) (*sns.Subscription, error) {
	protocol := d.Get("protocol").(string)
	endpoint := d.Get("endpoint").(string)
	topic_arn := d.Get("topic_arn").(string)

	req := &sns.ListSubscriptionsByTopicInput{
		TopicArn: aws.String(topic_arn),
	}

	for {

		res, err := snsconn.ListSubscriptionsByTopic(req)

		if err != nil {
			return nil, fmt.Errorf("Error fetching subscripitions for topic %s : %s", topic_arn, err)
		}

		for _, subscription := range res.Subscriptions {
			log.Printf("[DEBUG] check subscription with EndPoint %s, Protocol %s,  topicARN %s and SubscriptionARN %s", *subscription.Endpoint, *subscription.Protocol, *subscription.TopicArn, *subscription.SubscriptionArn)
			if *subscription.Endpoint == endpoint && *subscription.Protocol == protocol && *subscription.TopicArn == topic_arn && !subscriptionHasPendingConfirmation(subscription.SubscriptionArn) {
				return subscription, nil
			}
		}

		// if there are more than 100 subscriptions then go to the next 100 otherwise return nil
		if res.NextToken != nil {
			req.NextToken = res.NextToken
		} else {
			return nil, nil
		}
	}
}

// returns true if arn is nil or has both pending and confirmation words in the arn
func subscriptionHasPendingConfirmation(arn *string) bool {
	if arn != nil && !strings.Contains(strings.Replace(strings.ToLower(*arn), " ", "", -1), awsSNSPendingConfirmationMessageWithoutSpaces) {
		return false
	}

	return true
}
<|endoftext|>


<commit_before>package concourse

// Version is the version of Concourse. This variable is overridden at build
// time in the pipeline using ldflags.
var Version = "0.0.0-dev"

// WorkerVersion identifies compatibility between Concourse and a worker.
//
// Backwards-incompatible changes to the worker API should result in a major
// version bump.
//
// New features that are otherwise backwards-compatible should result in a
// minor version bump.
var WorkerVersion = "2.3"
<commit_msg>bump worker version to 2.4<commit_after>package concourse

// Version is the version of Concourse. This variable is overridden at build
// time in the pipeline using ldflags.
var Version = "0.0.0-dev"

// WorkerVersion identifies compatibility between Concourse and a worker.
//
// Backwards-incompatible changes to the worker API should result in a major
// version bump.
//
// New features that are otherwise backwards-compatible should result in a
// minor version bump.
var WorkerVersion = "2.4"
<|endoftext|>


<commit_before>//The server package privdes the basic gofire server
package server

import (
	//"encoding/json"
	"gofire/user"
	"net/http"
	//"net/url"
	//"time"
	//"strings"
)

type FireServer struct {
	RegisteredChatRooms []string    //All registered chatrooms
	User                []user.User `json:"-"` //All user on the chatroom
}

type FireServerHandler func(*FireServer, http.ResponseWriter, *http.Request)

func AddHandler(fireServer *FireServer, fn FireServerHandler) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, request *http.Request) {
		fn(fireServer, w, request)
	}
}

func NewFireServer() *FireServer{
	fireServer := &FireServer{
		RegisteredChatRooms: make([]string, 0),
		User:                make([]user.User, 0),
	}
	return fireServer
}
<commit_msg>added interface, so structs can be used as e.g. api controllers<commit_after>//The server package privdes the basic gofire server
package server

import (
	//"encoding/json"
	"gofire/user"
	"net/http"
	//"net/url"
	//"time"
	//"strings"
)

type FireServer struct {
	RegisteredChatRooms []string    //All registered chatrooms
	User                []user.User `json:"-"` //All user on the chatroom
}

type FireServerFunc func(*FireServer, http.ResponseWriter, *http.Request)

type FireServerHandler interface{
	Handle(*FireServer, http.ResponseWriter, *http.Request)
}

func AddHandleFunc(fireServer *FireServer, fn FireServerFunc) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, request *http.Request) {
		fn(fireServer, w, request)
	}
}

func AddHandler(fireServer *FireServer, handler FireServerHandler) func(http.ResponseWriter, *http.Request){
	return func(w http.ResponseWriter, request *http.Request){
		handler.Handle(fireServer, w, request)
	}

}

func NewFireServer() *FireServer{
	fireServer := &FireServer{
		RegisteredChatRooms: make([]string, 0),
		User:                make([]user.User, 0),
	}
	return fireServer
}
<|endoftext|>


<commit_before>package vm

import (
	"encoding/json"
	"fmt"
	u "github.com/araddon/gou"
	"math"
	"reflect"
	"strconv"
	"strings"
	"time"
)

var (
	_ = u.EMPTY
	//ReflectNilValue   = reflect.ValueOf((*interface{})(nil))
	//ReflectTrueValue  = reflect.ValueOf(true)
	//ReflectFalseValue = reflect.ValueOf(false)

	// our DataTypes we support, a limited sub-set of go
	floatRv   = reflect.ValueOf(float64(1.2))
	int64Rv   = reflect.ValueOf(int64(1))
	int32Rv   = reflect.ValueOf(int32(1))
	stringRv  = reflect.ValueOf("hello")
	stringsRv = reflect.ValueOf([]string{"hello"})
	boolRv    = reflect.ValueOf(true)
	mapIntRv  = reflect.ValueOf(map[string]int64{"hello": int64(1)})
	timeRv    = reflect.ValueOf(time.Time{})
	nilRv     = reflect.ValueOf(nil)

	RV_ZERO     = reflect.Value{}
	nilStruct   *emptyStruct
	EmptyStruct = struct{}{}

	BoolValueTrue     = NewBoolValue(true)
	BoolValueFalse    = NewBoolValue(false)
	NumberNaNValue    = NewNumberValue(math.NaN())
	EmptyStringValue  = NewStringValue("")
	EmptyStringsValue = NewStringsValue(nil)
	EmptyMapIntValue  = NewMapIntValue(make(map[string]int64))
	NilStructValue    = NewStructValue(nilStruct)
	TimeZeroValue     = NewTimeValue(time.Time{})
	ErrValue          = NewErrorValue("")

	_ Value = (StringValue)(EmptyStringValue)
)

type ValueType uint8

const (
	NilType ValueType = iota
	NumberType
	IntType
	BoolType
	TimeType
	StringType
	StringsType
	MapIntType
	SliceValueType
	StructType
	ErrorType
)

var typeStrings = []string{"nil", "number", "int", "bool", "time", "string", "[]string", "map[string]int", "[]value", "struct", "error"}

func (m ValueType) String() string { return typeStrings[m] }

type emptyStruct struct{}

type Value interface {
	// Is this a nil?  or empty string?
	Nil() bool
	// Is this an error, or unable to evaluate from Vm?
	Err() bool
	Value() interface{}
	Rv() reflect.Value
	ToString() string
	Type() ValueType
	//CanCoerce(rv reflect.Value) bool
}

type NumericValue interface {
	Float() float64
	Int() int64
}

func ValueTypeFromRT(rt reflect.Type) ValueType {
	switch rt {
	case reflect.TypeOf(NilValue{}):
		return NilType
	case reflect.TypeOf(NumberValue{}):
		return NumberType
	case reflect.TypeOf(IntValue{}):
		return IntType
	case reflect.TypeOf(TimeValue{}):
		return TimeType
	case reflect.TypeOf(BoolValue{}):
		return BoolType
	case reflect.TypeOf(StringValue{}):
		return StringType
	case reflect.TypeOf(StringsValue{}):
		return StringsType
	case reflect.TypeOf(MapIntValue{}):
		return MapIntType
	case reflect.TypeOf(SliceValue{}):
		return SliceValueType
	case reflect.TypeOf(MapIntValue{}):
		return MapIntType
	case reflect.TypeOf(StructValue{}):
		return StructType
	case reflect.TypeOf(ErrorValue{}):
		return ErrorType
	default:
		u.Warnf("Unrecognized Value Type Kind?  %v %T ", rt, rt)
	}
	return NilType
}

type NumberValue struct {
	v  float64
	rv reflect.Value
}

func NewNumberValue(v float64) NumberValue {
	return NumberValue{v: v, rv: reflect.ValueOf(v)}
}

func (m NumberValue) Nil() bool                         { return false }
func (m NumberValue) Err() bool                         { return false }
func (m NumberValue) Type() ValueType                   { return NumberType }
func (m NumberValue) Rv() reflect.Value                 { return m.rv }
func (m NumberValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(int64Rv, toRv) }
func (m NumberValue) Value() interface{}                { return m.v }
func (m NumberValue) MarshalJSON() ([]byte, error)      { return marshalFloat(float64(m.v)) }
func (m NumberValue) ToString() string                  { return strconv.FormatFloat(float64(m.v), 'f', -1, 64) }
func (m NumberValue) Float() float64                    { return m.v }
func (m NumberValue) Int() int64                        { return int64(m.v) }

type IntValue struct {
	v  int64
	rv reflect.Value
}

func NewIntValue(v int64) IntValue {
	return IntValue{v: v, rv: reflect.ValueOf(v)}
}

func (m IntValue) Nil() bool                         { return false }
func (m IntValue) Err() bool                         { return false }
func (m IntValue) Type() ValueType                   { return IntType }
func (m IntValue) Rv() reflect.Value                 { return m.rv }
func (m IntValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(int64Rv, toRv) }
func (m IntValue) Value() interface{}                { return m.v }
func (m IntValue) MarshalJSON() ([]byte, error)      { return marshalFloat(float64(m.v)) }
func (m IntValue) NumberValue() NumberValue          { return NewNumberValue(float64(m.v)) }
func (m IntValue) ToString() string                  { return strconv.FormatInt(m.v, 10) }
func (m IntValue) Float() float64                    { return float64(m.v) }
func (m IntValue) Int() int64                        { return m.v }

type BoolValue struct {
	v  bool
	rv reflect.Value
}

func NewBoolValue(v bool) BoolValue {
	return BoolValue{v: v, rv: reflect.ValueOf(v)}
}

func (m BoolValue) Nil() bool                         { return false }
func (m BoolValue) Err() bool                         { return false }
func (m BoolValue) Type() ValueType                   { return BoolType }
func (m BoolValue) Rv() reflect.Value                 { return m.rv }
func (m BoolValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(boolRv, toRv) }
func (m BoolValue) Value() interface{}                { return m.v }
func (m BoolValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m BoolValue) ToString() string                  { return strconv.FormatBool(m.v) }

type StringValue struct {
	v  string
	rv reflect.Value
}

func NewStringValue(v string) StringValue {
	return StringValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StringValue) Nil() bool                          { return len(m.v) == 0 }
func (m StringValue) Err() bool                          { return false }
func (m StringValue) Type() ValueType                    { return StringType }
func (m StringValue) Rv() reflect.Value                  { return m.rv }
func (m StringValue) CanCoerce(input reflect.Value) bool { return CanCoerce(stringRv, input) }
func (m StringValue) Value() interface{}                 { return m.v }
func (m StringValue) MarshalJSON() ([]byte, error)       { return json.Marshal(m.v) }
func (m StringValue) NumberValue() NumberValue           { return NewNumberValue(ToFloat64(m.Rv())) }
func (m StringValue) ToString() string                   { return m.v }

func (m StringValue) IntValue() IntValue {
	iv, _ := ToInt64(m.Rv())
	return NewIntValue(iv)
}

type StringsValue struct {
	v  []string
	rv reflect.Value
}

func NewStringsValue(v []string) StringsValue {
	return StringsValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StringsValue) Nil() bool                           { return len(m.v) == 0 }
func (m StringsValue) Err() bool                           { return false }
func (m StringsValue) Type() ValueType                     { return StringsType }
func (m StringsValue) Rv() reflect.Value                   { return m.rv }
func (m StringsValue) CanCoerce(boolRv reflect.Value) bool { return CanCoerce(stringRv, boolRv) }
func (m StringsValue) Value() interface{}                  { return m.v }
func (m *StringsValue) Append(sv string)                   { m.v = append(m.v, sv) }
func (m StringsValue) MarshalJSON() ([]byte, error)        { return json.Marshal(m.v) }
func (m StringsValue) Len() int                            { return len(m.v) }
func (m StringsValue) NumberValue() NumberValue {
	if len(m.v) == 1 {
		if fv, err := strconv.ParseFloat(m.v[0], 64); err == nil {
			return NewNumberValue(fv)
		}
	}

	return NumberNaNValue
}
func (m StringsValue) IntValue() IntValue {
	// Im not confident this is valid?   array first element?
	iv, _ := ToInt64(m.Rv())
	return NewIntValue(iv)
}
func (m StringsValue) ToString() string  { return strings.Join(m.v, ",") }
func (m StringsValue) Strings() []string { return m.v }
func (m StringsValue) Set() map[string]struct{} {
	setvals := make(map[string]struct{})
	for _, sv := range m.v {
		// Are we sure about this ToLower?
		//setvals[strings.ToLower(sv)] = EmptyStruct
		setvals[sv] = EmptyStruct
	}
	return setvals
}

type SliceValue struct {
	V  []Value
	rv reflect.Value
}

func NewSliceValues(v []Value) SliceValue {
	return SliceValue{V: v, rv: reflect.ValueOf(v)}
}

func (m SliceValue) Nil() bool                    { return len(m.V) == 0 }
func (m SliceValue) Err() bool                    { return false }
func (m SliceValue) Type() ValueType              { return SliceValueType }
func (m SliceValue) Rv() reflect.Value            { return m.rv }
func (m SliceValue) Value() interface{}           { return m.V }
func (m *SliceValue) Append(v Value)              { m.V = append(m.V, v) }
func (m SliceValue) MarshalJSON() ([]byte, error) { return json.Marshal(m.V) }
func (m SliceValue) Len() int                     { return len(m.V) }

type MapIntValue struct {
	v  map[string]int64
	rv reflect.Value
}

func NewMapIntValue(v map[string]int64) MapIntValue {
	return MapIntValue{v: v, rv: reflect.ValueOf(v)}
}

func (m MapIntValue) Nil() bool                         { return len(m.v) == 0 }
func (m MapIntValue) Err() bool                         { return false }
func (m MapIntValue) Type() ValueType                   { return MapIntType }
func (m MapIntValue) Rv() reflect.Value                 { return m.rv }
func (m MapIntValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(mapIntRv, toRv) }
func (m MapIntValue) Value() interface{}                { return m.v }
func (m MapIntValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m MapIntValue) ToString() string                  { return fmt.Sprintf("%v", m.v) }
func (m MapIntValue) MapInt() map[string]int64          { return m.v }

type StructValue struct {
	v  interface{}
	rv reflect.Value
}

func NewStructValue(v interface{}) StructValue {
	return StructValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StructValue) Nil() bool                         { return false }
func (m StructValue) Err() bool                         { return false }
func (m StructValue) Type() ValueType                   { return StructType }
func (m StructValue) Rv() reflect.Value                 { return m.rv }
func (m StructValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m StructValue) Value() interface{}                { return m.v }
func (m StructValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m StructValue) ToString() string                  { return fmt.Sprintf("%v", m.v) }

type TimeValue struct {
	t  time.Time
	rv reflect.Value
}

func NewTimeValue(t time.Time) TimeValue {
	return TimeValue{t: t, rv: reflect.ValueOf(t)}
}

func (m TimeValue) Nil() bool                         { return m.t.IsZero() }
func (m TimeValue) Err() bool                         { return false }
func (m TimeValue) Type() ValueType                   { return TimeType }
func (m TimeValue) Rv() reflect.Value                 { return m.rv }
func (m TimeValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(timeRv, toRv) }
func (m TimeValue) Value() interface{}                { return m.t }
func (m TimeValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.t) }
func (m TimeValue) ToString() string                  { return m.t.Format(time.RFC3339) }
func (m TimeValue) Time() time.Time                   { return m.t }

type ErrorValue struct {
	v  string
	rv reflect.Value
}

func NewErrorValue(v string) ErrorValue {
	return ErrorValue{v: v, rv: reflect.ValueOf(v)}
}

func (m ErrorValue) Nil() bool                         { return false }
func (m ErrorValue) Err() bool                         { return true }
func (m ErrorValue) Type() ValueType                   { return ErrorType }
func (m ErrorValue) Rv() reflect.Value                 { return m.rv }
func (m ErrorValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m ErrorValue) Value() interface{}                { return m.v }
func (m ErrorValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m ErrorValue) ToString() string                  { return "" }

type NilValue struct{}

func NewNilValue() NilValue {
	return NilValue{}
}

func (m NilValue) Nil() bool                         { return true }
func (m NilValue) Err() bool                         { return false }
func (m NilValue) Type() ValueType                   { return NilType }
func (m NilValue) Rv() reflect.Value                 { return nilRv }
func (m NilValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m NilValue) Value() interface{}                { return nil }
func (m NilValue) MarshalJSON() ([]byte, error)      { return nil, nil }
func (m NilValue) ToString() string                  { return "" }
<commit_msg>comments<commit_after>package vm

import (
	"encoding/json"
	"fmt"
	u "github.com/araddon/gou"
	"math"
	"reflect"
	"strconv"
	"strings"
	"time"
)

var (
	_ = u.EMPTY
	//ReflectNilValue   = reflect.ValueOf((*interface{})(nil))
	//ReflectTrueValue  = reflect.ValueOf(true)
	//ReflectFalseValue = reflect.ValueOf(false)

	// our DataTypes we support, a limited sub-set of go
	floatRv   = reflect.ValueOf(float64(1.2))
	int64Rv   = reflect.ValueOf(int64(1))
	int32Rv   = reflect.ValueOf(int32(1))
	stringRv  = reflect.ValueOf("hello")
	stringsRv = reflect.ValueOf([]string{"hello"})
	boolRv    = reflect.ValueOf(true)
	mapIntRv  = reflect.ValueOf(map[string]int64{"hello": int64(1)})
	timeRv    = reflect.ValueOf(time.Time{})
	nilRv     = reflect.ValueOf(nil)

	RV_ZERO     = reflect.Value{}
	nilStruct   *emptyStruct
	EmptyStruct = struct{}{}

	BoolValueTrue     = NewBoolValue(true)
	BoolValueFalse    = NewBoolValue(false)
	NumberNaNValue    = NewNumberValue(math.NaN())
	EmptyStringValue  = NewStringValue("")
	EmptyStringsValue = NewStringsValue(nil)
	EmptyMapIntValue  = NewMapIntValue(make(map[string]int64))
	NilStructValue    = NewStructValue(nilStruct)
	TimeZeroValue     = NewTimeValue(time.Time{})
	ErrValue          = NewErrorValue("")

	_ Value = (StringValue)(EmptyStringValue)
)

type ValueType uint8

const (
	NilType ValueType = iota
	NumberType
	IntType
	BoolType
	TimeType
	StringType
	StringsType
	MapIntType
	SliceValueType
	StructType
	ErrorType
)

var typeStrings = []string{"nil", "number", "int", "bool", "time", "string", "[]string", "map[string]int", "[]value", "struct", "error"}

func (m ValueType) String() string { return typeStrings[m] }

type emptyStruct struct{}

type Value interface {
	// Is this a nil?  or empty string?
	Nil() bool
	// Is this an error, or unable to evaluate from Vm?
	Err() bool
	Value() interface{}
	Rv() reflect.Value
	ToString() string
	Type() ValueType
	//CanCoerce(rv reflect.Value) bool
}

type NumericValue interface {
	Float() float64
	Int() int64
}

func ValueTypeFromRT(rt reflect.Type) ValueType {
	switch rt {
	case reflect.TypeOf(NilValue{}):
		return NilType
	case reflect.TypeOf(NumberValue{}):
		return NumberType
	case reflect.TypeOf(IntValue{}):
		return IntType
	case reflect.TypeOf(TimeValue{}):
		return TimeType
	case reflect.TypeOf(BoolValue{}):
		return BoolType
	case reflect.TypeOf(StringValue{}):
		return StringType
	case reflect.TypeOf(StringsValue{}):
		return StringsType
	case reflect.TypeOf(MapIntValue{}):
		return MapIntType
	case reflect.TypeOf(SliceValue{}):
		return SliceValueType
	case reflect.TypeOf(MapIntValue{}):
		return MapIntType
	case reflect.TypeOf(StructValue{}):
		return StructType
	case reflect.TypeOf(ErrorValue{}):
		return ErrorType
	default:
		// If type == Value, then it is not telling us what type
		// we should probably just allow it, as it is not telling us much
		// info but isn't wrong
		u.Warnf("Unrecognized Value Type Kind?  %v %T ", rt, rt)
		//panic("hmm")
	}
	return NilType
}

type NumberValue struct {
	v  float64
	rv reflect.Value
}

func NewNumberValue(v float64) NumberValue {
	return NumberValue{v: v, rv: reflect.ValueOf(v)}
}

func (m NumberValue) Nil() bool                         { return false }
func (m NumberValue) Err() bool                         { return false }
func (m NumberValue) Type() ValueType                   { return NumberType }
func (m NumberValue) Rv() reflect.Value                 { return m.rv }
func (m NumberValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(int64Rv, toRv) }
func (m NumberValue) Value() interface{}                { return m.v }
func (m NumberValue) MarshalJSON() ([]byte, error)      { return marshalFloat(float64(m.v)) }
func (m NumberValue) ToString() string                  { return strconv.FormatFloat(float64(m.v), 'f', -1, 64) }
func (m NumberValue) Float() float64                    { return m.v }
func (m NumberValue) Int() int64                        { return int64(m.v) }

type IntValue struct {
	v  int64
	rv reflect.Value
}

func NewIntValue(v int64) IntValue {
	return IntValue{v: v, rv: reflect.ValueOf(v)}
}

func (m IntValue) Nil() bool                         { return false }
func (m IntValue) Err() bool                         { return false }
func (m IntValue) Type() ValueType                   { return IntType }
func (m IntValue) Rv() reflect.Value                 { return m.rv }
func (m IntValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(int64Rv, toRv) }
func (m IntValue) Value() interface{}                { return m.v }
func (m IntValue) MarshalJSON() ([]byte, error)      { return marshalFloat(float64(m.v)) }
func (m IntValue) NumberValue() NumberValue          { return NewNumberValue(float64(m.v)) }
func (m IntValue) ToString() string                  { return strconv.FormatInt(m.v, 10) }
func (m IntValue) Float() float64                    { return float64(m.v) }
func (m IntValue) Int() int64                        { return m.v }

type BoolValue struct {
	v  bool
	rv reflect.Value
}

func NewBoolValue(v bool) BoolValue {
	return BoolValue{v: v, rv: reflect.ValueOf(v)}
}

func (m BoolValue) Nil() bool                         { return false }
func (m BoolValue) Err() bool                         { return false }
func (m BoolValue) Type() ValueType                   { return BoolType }
func (m BoolValue) Rv() reflect.Value                 { return m.rv }
func (m BoolValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(boolRv, toRv) }
func (m BoolValue) Value() interface{}                { return m.v }
func (m BoolValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m BoolValue) ToString() string                  { return strconv.FormatBool(m.v) }

type StringValue struct {
	v  string
	rv reflect.Value
}

func NewStringValue(v string) StringValue {
	return StringValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StringValue) Nil() bool                          { return len(m.v) == 0 }
func (m StringValue) Err() bool                          { return false }
func (m StringValue) Type() ValueType                    { return StringType }
func (m StringValue) Rv() reflect.Value                  { return m.rv }
func (m StringValue) CanCoerce(input reflect.Value) bool { return CanCoerce(stringRv, input) }
func (m StringValue) Value() interface{}                 { return m.v }
func (m StringValue) MarshalJSON() ([]byte, error)       { return json.Marshal(m.v) }
func (m StringValue) NumberValue() NumberValue           { return NewNumberValue(ToFloat64(m.Rv())) }
func (m StringValue) ToString() string                   { return m.v }

func (m StringValue) IntValue() IntValue {
	iv, _ := ToInt64(m.Rv())
	return NewIntValue(iv)
}

type StringsValue struct {
	v  []string
	rv reflect.Value
}

func NewStringsValue(v []string) StringsValue {
	return StringsValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StringsValue) Nil() bool                           { return len(m.v) == 0 }
func (m StringsValue) Err() bool                           { return false }
func (m StringsValue) Type() ValueType                     { return StringsType }
func (m StringsValue) Rv() reflect.Value                   { return m.rv }
func (m StringsValue) CanCoerce(boolRv reflect.Value) bool { return CanCoerce(stringRv, boolRv) }
func (m StringsValue) Value() interface{}                  { return m.v }
func (m *StringsValue) Append(sv string)                   { m.v = append(m.v, sv) }
func (m StringsValue) MarshalJSON() ([]byte, error)        { return json.Marshal(m.v) }
func (m StringsValue) Len() int                            { return len(m.v) }
func (m StringsValue) NumberValue() NumberValue {
	if len(m.v) == 1 {
		if fv, err := strconv.ParseFloat(m.v[0], 64); err == nil {
			return NewNumberValue(fv)
		}
	}

	return NumberNaNValue
}
func (m StringsValue) IntValue() IntValue {
	// Im not confident this is valid?   array first element?
	iv, _ := ToInt64(m.Rv())
	return NewIntValue(iv)
}
func (m StringsValue) ToString() string  { return strings.Join(m.v, ",") }
func (m StringsValue) Strings() []string { return m.v }
func (m StringsValue) Set() map[string]struct{} {
	setvals := make(map[string]struct{})
	for _, sv := range m.v {
		// Are we sure about this ToLower?
		//setvals[strings.ToLower(sv)] = EmptyStruct
		setvals[sv] = EmptyStruct
	}
	return setvals
}

type SliceValue struct {
	V  []Value
	rv reflect.Value
}

func NewSliceValues(v []Value) SliceValue {
	return SliceValue{V: v, rv: reflect.ValueOf(v)}
}

func (m SliceValue) Nil() bool                    { return len(m.V) == 0 }
func (m SliceValue) Err() bool                    { return false }
func (m SliceValue) Type() ValueType              { return SliceValueType }
func (m SliceValue) Rv() reflect.Value            { return m.rv }
func (m SliceValue) Value() interface{}           { return m.V }
func (m *SliceValue) Append(v Value)              { m.V = append(m.V, v) }
func (m SliceValue) MarshalJSON() ([]byte, error) { return json.Marshal(m.V) }
func (m SliceValue) Len() int                     { return len(m.V) }

type MapIntValue struct {
	v  map[string]int64
	rv reflect.Value
}

func NewMapIntValue(v map[string]int64) MapIntValue {
	return MapIntValue{v: v, rv: reflect.ValueOf(v)}
}

func (m MapIntValue) Nil() bool                         { return len(m.v) == 0 }
func (m MapIntValue) Err() bool                         { return false }
func (m MapIntValue) Type() ValueType                   { return MapIntType }
func (m MapIntValue) Rv() reflect.Value                 { return m.rv }
func (m MapIntValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(mapIntRv, toRv) }
func (m MapIntValue) Value() interface{}                { return m.v }
func (m MapIntValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m MapIntValue) ToString() string                  { return fmt.Sprintf("%v", m.v) }
func (m MapIntValue) MapInt() map[string]int64          { return m.v }

type StructValue struct {
	v  interface{}
	rv reflect.Value
}

func NewStructValue(v interface{}) StructValue {
	return StructValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StructValue) Nil() bool                         { return false }
func (m StructValue) Err() bool                         { return false }
func (m StructValue) Type() ValueType                   { return StructType }
func (m StructValue) Rv() reflect.Value                 { return m.rv }
func (m StructValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m StructValue) Value() interface{}                { return m.v }
func (m StructValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m StructValue) ToString() string                  { return fmt.Sprintf("%v", m.v) }

type TimeValue struct {
	t  time.Time
	rv reflect.Value
}

func NewTimeValue(t time.Time) TimeValue {
	return TimeValue{t: t, rv: reflect.ValueOf(t)}
}

func (m TimeValue) Nil() bool                         { return m.t.IsZero() }
func (m TimeValue) Err() bool                         { return false }
func (m TimeValue) Type() ValueType                   { return TimeType }
func (m TimeValue) Rv() reflect.Value                 { return m.rv }
func (m TimeValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(timeRv, toRv) }
func (m TimeValue) Value() interface{}                { return m.t }
func (m TimeValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.t) }
func (m TimeValue) ToString() string                  { return m.t.Format(time.RFC3339) }
func (m TimeValue) Time() time.Time                   { return m.t }

type ErrorValue struct {
	v  string
	rv reflect.Value
}

func NewErrorValue(v string) ErrorValue {
	return ErrorValue{v: v, rv: reflect.ValueOf(v)}
}

func (m ErrorValue) Nil() bool                         { return false }
func (m ErrorValue) Err() bool                         { return true }
func (m ErrorValue) Type() ValueType                   { return ErrorType }
func (m ErrorValue) Rv() reflect.Value                 { return m.rv }
func (m ErrorValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m ErrorValue) Value() interface{}                { return m.v }
func (m ErrorValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m ErrorValue) ToString() string                  { return "" }

type NilValue struct{}

func NewNilValue() NilValue {
	return NilValue{}
}

func (m NilValue) Nil() bool                         { return true }
func (m NilValue) Err() bool                         { return false }
func (m NilValue) Type() ValueType                   { return NilType }
func (m NilValue) Rv() reflect.Value                 { return nilRv }
func (m NilValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m NilValue) Value() interface{}                { return nil }
func (m NilValue) MarshalJSON() ([]byte, error)      { return nil, nil }
func (m NilValue) ToString() string                  { return "" }
<|endoftext|>


<commit_before>package ast

import (
	"github.com/chris-ramon/graphql-go/language/source"
)

type Location struct {
	Start  int
	End    int
	Source *source.Source
}

type Node interface {
}

// Name

type Name struct {
	Kind  string
	Loc   Location
	Value string
}

func NewName() *Name {
	return &Name{
		Kind: "Name",
	}
}

// Document

type Document struct {
	Kind        string
	Loc         Location
	Definitions []Definition
}

type Definition interface {
	// Most basic Definition interface
	GetKind() string
	GetLoc() Location

	// Some implementation may or may not have properties for these following getters()
	// But `executor` requires these getters().
	GetName() Name
	GetOperation() string
	GetVariableDefinitions() []VariableDefinition
	GetTypeCondition() NamedType
	GetDirectives() []Directive
	GetSelectionSet() SelectionSet

}

//
//type OperationDefinition struct {
//	Kind               string
//	Loc                Location
//	Operation          string
//	Name               Name
//	VariableDefinition []VariableDefinition
//	Directives         []Directive
//	SelectionSet       SelectionSet
//}

type VariableDefinition struct {
	Kind         string
	Loc          Location
	Variable     Variable
	Type         interface{}
	DefaultValue Value
}

func NewVariableDefinition() *VariableDefinition {
	return &VariableDefinition{
		Kind: "VariableDefinition",
	}
}

type Variable struct {
	Kind string
	Loc  Location
	Name Name
}

func NewVariable() *Variable {
	return &Variable{
		Kind: "Variable",
	}
}

type SelectionSet struct {
	Kind       string
	Loc        Location
	Selections []interface{}
}

type Selection interface{}

func NewSelectionSet() *SelectionSet {
	return &SelectionSet{
		Kind: "SelectionSet",
	}
}

type Field struct {
	Kind         string
	Loc          Location
	Alias        Name
	Name         Name
	Arguments    []Argument
	Directives   []Directive
	SelectionSet SelectionSet
}

func NewField() *Name {
	return &Name{
		Kind: "Field",
	}
}

type Argument struct {
	Kind  string
	Loc   Location
	Name  Name
	Value Value
}

func NewArgument() *Name {
	return &Name{
		Kind: "Argument",
	}
}

// Fragments

type FragmentSpread struct {
	Kind       string
	Loc        Location
	Name       Name
	Directives []Directive
}

type InlineFragment struct {
	Kind          string
	Loc           Location
	TypeCondition NamedType
	Directives    []Directive
	SelectionSet  SelectionSet
}

//type FragmentDefinition struct {
//	Kind          string
//	Loc           Location
//	Name          Name
//	TypeCondition NamedType
//	Directives    []Directive
//	SelectionSet  SelectionSet
//}

// Values

type Value interface {
	//GetKind() string
	//GetLoc() Location
	//GetName() Name
}

type IntValue struct {
	Kind  string
	Loc   Location
	Value string
}

type FloatValue struct {
	Kind  string
	Loc   Location
	Value string
}

type StringValue struct {
	Kind  string
	Loc   Location
	Value string
}

type BooleanValue struct {
	Kind  string
	Loc   Location
	Value bool
}

type EnumValue struct {
	Kind  string
	Loc   Location
	Value string
}

type ListValue struct {
	Kind   string
	Loc    Location
	Values []Value
}

type ObjectValue struct {
	Kind   string
	Loc    Location
	Fields []ObjectField
}

type ObjectField struct {
	Kind  string
	Name  Name
	Loc   Location
	Value Value
}

// Type does not exists in graphql-js ast
type ArrayValue struct {
	Kind   string
	Loc    Location
	Values []Value
}

// Directives

// why?
//type Directive struct {
//	Kind  string
//	Loc   Location
//	Name  Name
//	Value Value
//}

type Directive struct {
	Kind      string
	Loc       Location
	Name      Name
	Arguments []Argument
}

func NewDirective() *Directive {
	return &Directive{
		Kind: "Directive",
	}
}

// Type Reference

type Type interface{}

type NamedType struct {
	Kind string
	Loc  Location
	Name Name
	Type Type
}

type ListType struct {
	Kind string
	Loc  Location
	Type Type
}

type NonNullType struct {
	Kind string
	Loc  Location
	Type Type
}

// TODO: Type Definitions

type TypeDefinition interface{}

type FieldDefinition struct {
	Kind      string
	Loc       Location
	Name      Name
	Arguments []InputValueDefinition
	Type      Type
}

type InputValueDefinition struct {
	Kind         string
	Loc          Location
	Name         Name
	Type         Type
	DefaultValue Value
}

type EnumValueDefinition struct {
	Kind string
	Loc  Location
	Name Name
}
<commit_msg>Minor code clean up - Removed commented out sections in `ast.go`<commit_after>package ast

import (
	"github.com/chris-ramon/graphql-go/language/source"
)

type Location struct {
	Start  int
	End    int
	Source *source.Source
}

type Node interface {
}

// Name

type Name struct {
	Kind  string
	Loc   Location
	Value string
}

func NewName() *Name {
	return &Name{
		Kind: "Name",
	}
}

// Document

type Document struct {
	Kind        string
	Loc         Location
	Definitions []Definition
}

type Definition interface {
	// Most basic Definition interface
	GetKind() string
	GetLoc() Location

	// Some implementation may or may not have properties for these following getters()
	// But `executor` requires these getters().
	GetName() Name
	GetOperation() string
	GetVariableDefinitions() []VariableDefinition
	GetTypeCondition() NamedType
	GetDirectives() []Directive
	GetSelectionSet() SelectionSet

}

type VariableDefinition struct {
	Kind         string
	Loc          Location
	Variable     Variable
	Type         interface{}
	DefaultValue Value
}

func NewVariableDefinition() *VariableDefinition {
	return &VariableDefinition{
		Kind: "VariableDefinition",
	}
}

type Variable struct {
	Kind string
	Loc  Location
	Name Name
}

func NewVariable() *Variable {
	return &Variable{
		Kind: "Variable",
	}
}

type SelectionSet struct {
	Kind       string
	Loc        Location
	Selections []interface{}
}

type Selection interface{}

func NewSelectionSet() *SelectionSet {
	return &SelectionSet{
		Kind: "SelectionSet",
	}
}

type Field struct {
	Kind         string
	Loc          Location
	Alias        Name
	Name         Name
	Arguments    []Argument
	Directives   []Directive
	SelectionSet SelectionSet
}

func NewField() *Name {
	return &Name{
		Kind: "Field",
	}
}

type Argument struct {
	Kind  string
	Loc   Location
	Name  Name
	Value Value
}

func NewArgument() *Name {
	return &Name{
		Kind: "Argument",
	}
}

// Fragments

type FragmentSpread struct {
	Kind       string
	Loc        Location
	Name       Name
	Directives []Directive
}

type InlineFragment struct {
	Kind          string
	Loc           Location
	TypeCondition NamedType
	Directives    []Directive
	SelectionSet  SelectionSet
}

// Values

type Value interface {
	//GetKind() string
	//GetLoc() Location
	//GetName() Name
}

type IntValue struct {
	Kind  string
	Loc   Location
	Value string
}

type FloatValue struct {
	Kind  string
	Loc   Location
	Value string
}

type StringValue struct {
	Kind  string
	Loc   Location
	Value string
}

type BooleanValue struct {
	Kind  string
	Loc   Location
	Value bool
}

type EnumValue struct {
	Kind  string
	Loc   Location
	Value string
}

type ListValue struct {
	Kind   string
	Loc    Location
	Values []Value
}

type ObjectValue struct {
	Kind   string
	Loc    Location
	Fields []ObjectField
}

type ObjectField struct {
	Kind  string
	Name  Name
	Loc   Location
	Value Value
}

// Type does not exists in graphql-js ast
type ArrayValue struct {
	Kind   string
	Loc    Location
	Values []Value
}

// Directives

// why?
//type Directive struct {
//	Kind  string
//	Loc   Location
//	Name  Name
//	Value Value
//}

type Directive struct {
	Kind      string
	Loc       Location
	Name      Name
	Arguments []Argument
}

func NewDirective() *Directive {
	return &Directive{
		Kind: "Directive",
	}
}

// Type Reference

type Type interface{}

type NamedType struct {
	Kind string
	Loc  Location
	Name Name
	Type Type
}

type ListType struct {
	Kind string
	Loc  Location
	Type Type
}

type NonNullType struct {
	Kind string
	Loc  Location
	Type Type
}

// TODO: Type Definitions

type TypeDefinition interface{}

type FieldDefinition struct {
	Kind      string
	Loc       Location
	Name      Name
	Arguments []InputValueDefinition
	Type      Type
}

type InputValueDefinition struct {
	Kind         string
	Loc          Location
	Name         Name
	Type         Type
	DefaultValue Value
}

type EnumValueDefinition struct {
	Kind string
	Loc  Location
	Name Name
}
<|endoftext|>


<commit_before>// Copyright 2015 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package ddl

import (
	"github.com/juju/errors"
	"github.com/pingcap/tidb/infoschema"
	"github.com/pingcap/tidb/kv"
	"github.com/pingcap/tidb/meta"
	"github.com/pingcap/tidb/meta/autoid"
	"github.com/pingcap/tidb/model"
	"github.com/pingcap/tidb/table"
	"github.com/pingcap/tidb/tablecodec"
	"github.com/pingcap/tidb/terror"
)

func (d *ddl) onCreateTable(t *meta.Meta, job *model.Job) error {
	schemaID := job.SchemaID
	tbInfo := &model.TableInfo{}
	if err := job.DecodeArgs(tbInfo); err != nil {
		// Invalid arguments, cancel this job.
		job.State = model.JobCancelled
		return errors.Trace(err)
	}

	tbInfo.State = model.StateNone
	err := checkTableNotExists(t, job, schemaID, tbInfo.Name.L)
	if err != nil {
		return errors.Trace(err)
	}

	ver, err := updateSchemaVersion(t, job)
	if err != nil {
		return errors.Trace(err)
	}

	switch tbInfo.State {
	case model.StateNone:
		// none -> public
		job.SchemaState = model.StatePublic
		tbInfo.State = model.StatePublic
		err = t.CreateTable(schemaID, tbInfo)
		if err != nil {
			return errors.Trace(err)
		}
		// Finish this job.
		job.State = model.JobDone
		job.BinlogInfo.AddTableInfo(ver, tbInfo)
		return nil
	default:
		return ErrInvalidTableState.Gen("invalid table state %v", tbInfo.State)
	}
}

func (d *ddl) onDropTable(t *meta.Meta, job *model.Job) error {
	schemaID := job.SchemaID
	tableID := job.TableID

	// Check this table's database.
	tblInfo, err := t.GetTable(schemaID, tableID)
	if err != nil {
		if terror.ErrorEqual(err, meta.ErrDBNotExists) {
			job.State = model.JobCancelled
			return errors.Trace(infoschema.ErrDatabaseNotExists)
		}
		return errors.Trace(err)
	}

	// Check the table.
	if tblInfo == nil {
		job.State = model.JobCancelled
		return errors.Trace(infoschema.ErrTableNotExists)
	}

	ver, err := updateSchemaVersion(t, job)
	if err != nil {
		return errors.Trace(err)
	}

	switch tblInfo.State {
	case model.StatePublic:
		// public -> write only
		job.SchemaState = model.StateWriteOnly
		tblInfo.State = model.StateWriteOnly
		err = t.UpdateTable(schemaID, tblInfo)
	case model.StateWriteOnly:
		// write only -> delete only
		job.SchemaState = model.StateDeleteOnly
		tblInfo.State = model.StateDeleteOnly
		err = t.UpdateTable(schemaID, tblInfo)
	case model.StateDeleteOnly:
		tblInfo.State = model.StateNone
		err = t.UpdateTable(schemaID, tblInfo)
		if err = t.DropTable(job.SchemaID, job.TableID); err != nil {
			break
		}
		// Finish this job.
		job.State = model.JobDone
		job.SchemaState = model.StateNone
		job.BinlogInfo.AddTableInfo(ver, tblInfo)
		startKey := tablecodec.EncodeTablePrefix(tableID)
		job.Args = append(job.Args, startKey)
	default:
		err = ErrInvalidTableState.Gen("invalid table state %v", tblInfo.State)
	}

	return errors.Trace(err)
}

// Maximum number of keys to delete for each reorg table job run.
var reorgTableDeleteLimit = 65536

func (d *ddl) delReorgTable(t *meta.Meta, job *model.Job) error {
	var startKey kv.Key
	if err := job.DecodeArgs(&startKey); err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}

	limit := reorgTableDeleteLimit
	delCount, err := d.dropTableData(startKey, job, limit)
	if err != nil {
		return errors.Trace(err)
	}
	// Finish this background job.
	if delCount < limit {
		job.SchemaState = model.StateNone
		job.State = model.JobDone
	}
	return nil
}

func (d *ddl) getTable(schemaID int64, tblInfo *model.TableInfo) (table.Table, error) {
	if tblInfo.OldSchemaID != 0 {
		schemaID = tblInfo.OldSchemaID
	}
	alloc := autoid.NewAllocator(d.store, schemaID)
	tbl, err := table.TableFromMeta(alloc, tblInfo)
	return tbl, errors.Trace(err)
}

func getTableInfo(t *meta.Meta, job *model.Job, schemaID int64) (*model.TableInfo, error) {
	tableID := job.TableID
	tblInfo, err := t.GetTable(schemaID, tableID)
	if err != nil {
		if terror.ErrorEqual(err, meta.ErrDBNotExists) {
			job.State = model.JobCancelled
			return nil, errors.Trace(infoschema.ErrDatabaseNotExists)
		}
		return nil, errors.Trace(err)
	} else if tblInfo == nil {
		job.State = model.JobCancelled
		return nil, errors.Trace(infoschema.ErrTableNotExists)
	}

	if tblInfo.State != model.StatePublic {
		job.State = model.JobCancelled
		return nil, ErrInvalidTableState.Gen("table %s is not in public, but %s", tblInfo.Name, tblInfo.State)
	}

	return tblInfo, nil
}

// dropTableData deletes data in a limited number. If limit < 0, deletes all data.
func (d *ddl) dropTableData(startKey kv.Key, job *model.Job, limit int) (int, error) {
	prefix := tablecodec.EncodeTablePrefix(job.TableID)
	delCount, nextStartKey, err := d.delKeysWithStartKey(prefix, startKey, bgJobFlag, job, limit)
	job.Args = []interface{}{nextStartKey}
	return delCount, errors.Trace(err)
}

// onTruncateTable delete old table meta, and creates a new table identical to old table except for table ID.
// As all the old data is encoded with old table ID, it can not be accessed any more.
// A background job will be created to delete old data.
func (d *ddl) onTruncateTable(t *meta.Meta, job *model.Job) error {
	schemaID := job.SchemaID
	tableID := job.TableID
	var newTableID int64
	err := job.DecodeArgs(&newTableID)
	if err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}
	tblInfo, err := getTableInfo(t, job, schemaID)
	if err != nil {
		return errors.Trace(err)
	}

	err = t.DropTable(schemaID, tableID)
	if err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}
	tblInfo.ID = newTableID
	err = t.CreateTable(schemaID, tblInfo)
	if err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}

	ver, err := updateSchemaVersion(t, job)
	if err != nil {
		return errors.Trace(err)
	}
	job.State = model.JobDone
	job.BinlogInfo.AddTableInfo(ver, tblInfo)
	startKey := tablecodec.EncodeTablePrefix(tableID)
	job.Args = []interface{}{startKey}
	return nil
}

func (d *ddl) onRenameTable(t *meta.Meta, job *model.Job) error {
	var oldSchemaID int64
	var tableName model.CIStr
	if err := job.DecodeArgs(&oldSchemaID, &tableName); err != nil {
		// Invalid arguments, cancel this job.
		job.State = model.JobCancelled
		return errors.Trace(err)
	}

	tblInfo, err := getTableInfo(t, job, oldSchemaID)
	if err != nil {
		return errors.Trace(err)
	}
	newSchemaID := job.SchemaID
	if newSchemaID != oldSchemaID {
		err = checkTableNotExists(t, job, newSchemaID, tblInfo.Name.L)
		if err != nil {
			return errors.Trace(err)
		}
		if tblInfo.OldSchemaID == 0 {
			tblInfo.OldSchemaID = oldSchemaID
		}
	}

	err = t.DropTable(oldSchemaID, tblInfo.ID)
	if err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}
	tblInfo.Name = tableName
	err = t.CreateTable(newSchemaID, tblInfo)
	if err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}

	ver, err := updateSchemaVersion(t, job)
	if err != nil {
		return errors.Trace(err)
	}
	job.State = model.JobDone
	job.SchemaState = model.StatePublic
	job.BinlogInfo.AddTableInfo(ver, tblInfo)
	return nil
}

func checkTableNotExists(t *meta.Meta, job *model.Job, schemaID int64, tableName string) error {
	// Check this table's database.
	tables, err := t.ListTables(schemaID)
	if err != nil {
		if terror.ErrorEqual(err, meta.ErrDBNotExists) {
			job.State = model.JobCancelled
			return errors.Trace(infoschema.ErrDatabaseNotExists)
		}
		return errors.Trace(err)
	}

	// Check the table.
	for _, tbl := range tables {
		if tbl.Name.L == tableName {
			// This table already exists and can't be created, we should cancel this job now.
			job.State = model.JobCancelled
			return infoschema.ErrTableExists.GenByArgs(tbl.Name)
		}
	}

	return nil
}
<commit_msg>ddl: fix the bug of %!(MISSING) in error message (#2727)<commit_after>// Copyright 2015 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package ddl

import (
	"github.com/juju/errors"
	"github.com/pingcap/tidb/infoschema"
	"github.com/pingcap/tidb/kv"
	"github.com/pingcap/tidb/meta"
	"github.com/pingcap/tidb/meta/autoid"
	"github.com/pingcap/tidb/model"
	"github.com/pingcap/tidb/table"
	"github.com/pingcap/tidb/tablecodec"
	"github.com/pingcap/tidb/terror"
)

func (d *ddl) onCreateTable(t *meta.Meta, job *model.Job) error {
	schemaID := job.SchemaID
	tbInfo := &model.TableInfo{}
	if err := job.DecodeArgs(tbInfo); err != nil {
		// Invalid arguments, cancel this job.
		job.State = model.JobCancelled
		return errors.Trace(err)
	}

	tbInfo.State = model.StateNone
	err := checkTableNotExists(t, job, schemaID, tbInfo.Name.L)
	if err != nil {
		return errors.Trace(err)
	}

	ver, err := updateSchemaVersion(t, job)
	if err != nil {
		return errors.Trace(err)
	}

	switch tbInfo.State {
	case model.StateNone:
		// none -> public
		job.SchemaState = model.StatePublic
		tbInfo.State = model.StatePublic
		err = t.CreateTable(schemaID, tbInfo)
		if err != nil {
			return errors.Trace(err)
		}
		// Finish this job.
		job.State = model.JobDone
		job.BinlogInfo.AddTableInfo(ver, tbInfo)
		return nil
	default:
		return ErrInvalidTableState.Gen("invalid table state %v", tbInfo.State)
	}
}

func (d *ddl) onDropTable(t *meta.Meta, job *model.Job) error {
	schemaID := job.SchemaID
	tableID := job.TableID

	// Check this table's database.
	tblInfo, err := t.GetTable(schemaID, tableID)
	if err != nil {
		if terror.ErrorEqual(err, meta.ErrDBNotExists) {
			job.State = model.JobCancelled
			return errors.Trace(infoschema.ErrDatabaseNotExists)
		}
		return errors.Trace(err)
	}

	// Check the table.
	if tblInfo == nil {
		job.State = model.JobCancelled
		return errors.Trace(infoschema.ErrTableNotExists)
	}

	ver, err := updateSchemaVersion(t, job)
	if err != nil {
		return errors.Trace(err)
	}

	switch tblInfo.State {
	case model.StatePublic:
		// public -> write only
		job.SchemaState = model.StateWriteOnly
		tblInfo.State = model.StateWriteOnly
		err = t.UpdateTable(schemaID, tblInfo)
	case model.StateWriteOnly:
		// write only -> delete only
		job.SchemaState = model.StateDeleteOnly
		tblInfo.State = model.StateDeleteOnly
		err = t.UpdateTable(schemaID, tblInfo)
	case model.StateDeleteOnly:
		tblInfo.State = model.StateNone
		err = t.UpdateTable(schemaID, tblInfo)
		if err = t.DropTable(job.SchemaID, job.TableID); err != nil {
			break
		}
		// Finish this job.
		job.State = model.JobDone
		job.SchemaState = model.StateNone
		job.BinlogInfo.AddTableInfo(ver, tblInfo)
		startKey := tablecodec.EncodeTablePrefix(tableID)
		job.Args = append(job.Args, startKey)
	default:
		err = ErrInvalidTableState.Gen("invalid table state %v", tblInfo.State)
	}

	return errors.Trace(err)
}

// Maximum number of keys to delete for each reorg table job run.
var reorgTableDeleteLimit = 65536

func (d *ddl) delReorgTable(t *meta.Meta, job *model.Job) error {
	var startKey kv.Key
	if err := job.DecodeArgs(&startKey); err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}

	limit := reorgTableDeleteLimit
	delCount, err := d.dropTableData(startKey, job, limit)
	if err != nil {
		return errors.Trace(err)
	}
	// Finish this background job.
	if delCount < limit {
		job.SchemaState = model.StateNone
		job.State = model.JobDone
	}
	return nil
}

func (d *ddl) getTable(schemaID int64, tblInfo *model.TableInfo) (table.Table, error) {
	if tblInfo.OldSchemaID != 0 {
		schemaID = tblInfo.OldSchemaID
	}
	alloc := autoid.NewAllocator(d.store, schemaID)
	tbl, err := table.TableFromMeta(alloc, tblInfo)
	return tbl, errors.Trace(err)
}

func getTableInfo(t *meta.Meta, job *model.Job, schemaID int64) (*model.TableInfo, error) {
	tableID := job.TableID
	tblInfo, err := t.GetTable(schemaID, tableID)
	if err != nil {
		if terror.ErrorEqual(err, meta.ErrDBNotExists) {
			job.State = model.JobCancelled
			return nil, errors.Trace(infoschema.ErrDatabaseNotExists)
		}
		return nil, errors.Trace(err)
	} else if tblInfo == nil {
		job.State = model.JobCancelled
		return nil, errors.Trace(infoschema.ErrTableNotExists)
	}

	if tblInfo.State != model.StatePublic {
		job.State = model.JobCancelled
		return nil, ErrInvalidTableState.Gen("table %s is not in public, but %s", tblInfo.Name, tblInfo.State)
	}

	return tblInfo, nil
}

// dropTableData deletes data in a limited number. If limit < 0, deletes all data.
func (d *ddl) dropTableData(startKey kv.Key, job *model.Job, limit int) (int, error) {
	prefix := tablecodec.EncodeTablePrefix(job.TableID)
	delCount, nextStartKey, err := d.delKeysWithStartKey(prefix, startKey, bgJobFlag, job, limit)
	job.Args = []interface{}{nextStartKey}
	return delCount, errors.Trace(err)
}

// onTruncateTable delete old table meta, and creates a new table identical to old table except for table ID.
// As all the old data is encoded with old table ID, it can not be accessed any more.
// A background job will be created to delete old data.
func (d *ddl) onTruncateTable(t *meta.Meta, job *model.Job) error {
	schemaID := job.SchemaID
	tableID := job.TableID
	var newTableID int64
	err := job.DecodeArgs(&newTableID)
	if err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}
	tblInfo, err := getTableInfo(t, job, schemaID)
	if err != nil {
		return errors.Trace(err)
	}

	err = t.DropTable(schemaID, tableID)
	if err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}
	tblInfo.ID = newTableID
	err = t.CreateTable(schemaID, tblInfo)
	if err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}

	ver, err := updateSchemaVersion(t, job)
	if err != nil {
		return errors.Trace(err)
	}
	job.State = model.JobDone
	job.BinlogInfo.AddTableInfo(ver, tblInfo)
	startKey := tablecodec.EncodeTablePrefix(tableID)
	job.Args = []interface{}{startKey}
	return nil
}

func (d *ddl) onRenameTable(t *meta.Meta, job *model.Job) error {
	var oldSchemaID int64
	var tableName model.CIStr
	if err := job.DecodeArgs(&oldSchemaID, &tableName); err != nil {
		// Invalid arguments, cancel this job.
		job.State = model.JobCancelled
		return errors.Trace(err)
	}

	tblInfo, err := getTableInfo(t, job, oldSchemaID)
	if err != nil {
		return errors.Trace(err)
	}
	newSchemaID := job.SchemaID
	if newSchemaID != oldSchemaID {
		err = checkTableNotExists(t, job, newSchemaID, tblInfo.Name.L)
		if err != nil {
			return errors.Trace(err)
		}
		if tblInfo.OldSchemaID == 0 {
			tblInfo.OldSchemaID = oldSchemaID
		}
	}

	err = t.DropTable(oldSchemaID, tblInfo.ID)
	if err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}
	tblInfo.Name = tableName
	err = t.CreateTable(newSchemaID, tblInfo)
	if err != nil {
		job.State = model.JobCancelled
		return errors.Trace(err)
	}

	ver, err := updateSchemaVersion(t, job)
	if err != nil {
		return errors.Trace(err)
	}
	job.State = model.JobDone
	job.SchemaState = model.StatePublic
	job.BinlogInfo.AddTableInfo(ver, tblInfo)
	return nil
}

func checkTableNotExists(t *meta.Meta, job *model.Job, schemaID int64, tableName string) error {
	// Check this table's database.
	tables, err := t.ListTables(schemaID)
	if err != nil {
		if terror.ErrorEqual(err, meta.ErrDBNotExists) {
			job.State = model.JobCancelled
			return infoschema.ErrDatabaseNotExists.GenByArgs("")
		}
		return errors.Trace(err)
	}

	// Check the table.
	for _, tbl := range tables {
		if tbl.Name.L == tableName {
			// This table already exists and can't be created, we should cancel this job now.
			job.State = model.JobCancelled
			return infoschema.ErrTableExists.GenByArgs(tbl.Name)
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package emoji

import (
	"regexp"
	"strings"
)

const gomojiRaw string = `
:+1: +1
:angry:	:@
:broken_heart:	</3
:confused:	>:\
:cry:	:'(
:disappointed:	:(
:dizzy_face:	#)
:expressionless:	-_-
:fearful:	D:
:flushed:	:$
:frowning: :(
:heart:	<3
:innocent:	O:)
:joy:	:')
:kissing_heart:	:^*
:laughing:	>:)
:no_mouth:	:X
:ok_woman:	*\0/*
:open_mouth:	>:O
:persevere:	>.<
:slight_smile:	:)
:smiley:	:D
:stuck_out_tongue:	:P
:stuck_out_tongue_winking_eye:	>:P
:sunglasses:	B)
:sweat:	':(
:sweat_smile:	':)
:wink:	;)`

func GetEmojiToAsciiMap() map[string]Emoji {
	data := map[string]Emoji{}
	rx := regexp.MustCompile(`\s+`)
	lines := strings.Split(gomojiRaw, "\n")
	for _, line := range lines {
		line = strings.TrimSpace(line)
		line = rx.ReplaceAllString(line, " ")
		parts := strings.Split(line, " ")
		if len(parts) == 2 {
			emoji := Emoji{
				Emoji: parts[0],
				Ascii: parts[1],
				Regex: regexp.MustCompile(regexp.QuoteMeta(parts[0]))}
			data[parts[0]] = emoji
		}
	}
	return data
}

type Emoji struct {
	Ascii string
	Emoji string
	Regex *regexp.Regexp
}

type Converter struct {
	data map[string]Emoji
}

func NewConverter() Converter {
	return Converter{data: GetEmojiToAsciiMap()}
}

func (conv *Converter) EmojiToAscii(input string) string {
	rx := regexp.MustCompile(`:\+?[0-9a-z_]+:`)
	matches := rx.FindAllString(input, -1)
	output := input
	for _, emo := range matches {
		if einfo, ok := conv.data[emo]; ok {
			output = einfo.Regex.ReplaceAllString(output, einfo.Ascii)
		}
	}
	return output
}
<commit_msg>add text/emoji Unicode support<commit_after>package emoji

/*
https://emojipedia.org/github/
http://emojicodes.com/
https://unicode.org/emoji/charts/full-emoji-list.html
*/

import (
	"regexp"
	"strings"
)

const gomojiRaw string = `
:+1: +1
:angry:	:@
:broken_heart:	</3
:confused:	>:\
:cry:	:'(
:disappointed:	:(
:dizzy_face:	#)
:expressionless:	-_-
:fearful:	D:
:flushed:	:$
:frowning: :( 🙁
:heart:	<3
:innocent:	O:)
:joy:	:')
:kissing_heart:	:^*
:laughing:	>:)
:no_mouth:	:X
:ok_woman:	*\0/*
:open_mouth:	>:O
:persevere:	>.<
:slight_smile:	:)
:smile: :) 😀
:smiley:	:D
:stuck_out_tongue:	:P
:stuck_out_tongue_winking_eye:	>:P
:sunglasses:	B)
:sweat:	':(
:sweat_smile:	':)
:wink: ;) 😉`

func GetEmojiToAsciiMap() map[string]Emoji {
	data := map[string]Emoji{}
	rx := regexp.MustCompile(`\s+`)
	lines := strings.Split(gomojiRaw, "\n")
	for _, line := range lines {
		line = strings.TrimSpace(line)
		line = rx.ReplaceAllString(line, " ")
		parts := strings.Split(line, " ")
		if len(parts) == 2 || len(parts) == 3 {
			emo := Emoji{
				Shortcode:   strings.TrimSpace(parts[0]),
				Ascii:       strings.TrimSpace(parts[1]),
				ShortcodeRx: regexp.MustCompile(regexp.QuoteMeta(parts[0]))}
			if len(parts) == 3 {
				emo.Unicode = strings.TrimSpace(parts[2])
			}
			data[parts[0]] = emo
		}
	}
	return data
}

type Emoji struct {
	Ascii       string
	Shortcode   string
	Unicode     string
	ShortcodeRx *regexp.Regexp
}

type Converter struct {
	data       map[string]Emoji
	UseUnicode bool
}

func NewConverter() Converter {
	return Converter{
		data:       GetEmojiToAsciiMap(),
		UseUnicode: true}
}

func (conv *Converter) EmojiToAscii(input string) string {
	rx := regexp.MustCompile(`:\+?[0-9a-z_]+:`)
	matches := rx.FindAllString(input, -1)
	output := input
	for _, emo := range matches {
		if einfo, ok := conv.data[emo]; ok {
			if conv.UseUnicode && len(einfo.Unicode) > 0 {
				output = einfo.ShortcodeRx.ReplaceAllString(output, einfo.Unicode)
			} else {
				output = einfo.ShortcodeRx.ReplaceAllString(output, einfo.Ascii)
			}
		}
	}
	return output
}
<|endoftext|>


<commit_before>package lists

import (
	"bytes"
	"math"

	"github.com/zimmski/tavor/rand"
	"github.com/zimmski/tavor/token"
)

type Repeat struct {
	from  int64
	to    int64
	token token.Token
	value []token.Token
}

func NewRepeat(tok token.Token, from, to int64) *Repeat {
	l := &Repeat{
		from:  from,
		to:    to,
		token: tok,
		value: make([]token.Token, from),
	}

	for i := range l.value {
		l.value[i] = tok.Clone()
	}

	return l
}

// Token interface methods

func (l *Repeat) Clone() token.Token {
	c := Repeat{
		from:  l.from,
		to:    l.to,
		token: l.token.Clone(),
		value: make([]token.Token, len(l.value)),
	}

	for i, tok := range l.value {
		c.value[i] = tok.Clone()
	}

	return &c
}

func (l *Repeat) Fuzz(r rand.Rand) {
	i := r.Intn(int(l.to - l.from + 1))

	l.permutation(i)
}

func (l *Repeat) FuzzAll(r rand.Rand) {
	l.Fuzz(r)

	for _, tok := range l.value {
		tok.FuzzAll(r)
	}
}

func (l *Repeat) Parse(pars *token.InternalParser, cur int) (int, []error) {
	var toks []token.Token

	for i := 1; i <= int(l.from); i++ {
		tok := l.token.Clone()

		nex, errs := tok.Parse(pars, cur)

		if len(errs) != 0 {
			return cur, errs
		}

		cur = nex
		toks = append(toks, tok)
	}

	for i := l.from; i < l.to; i++ {
		tok := l.token.Clone()

		nex, errs := tok.Parse(pars, cur)

		if len(errs) != 0 {
			break
		}

		cur = nex
		toks = append(toks, tok)
	}

	l.value = toks

	return cur, nil
}

func (l *Repeat) permutation(i int) {
	toks := make([]token.Token, i+int(l.from))

	for i := range toks {
		toks[i] = l.token.Clone()
	}

	l.value = toks
}

func (l *Repeat) Permutation(i int) error {
	permutations := l.Permutations()

	if i < 1 || i > permutations {
		return &token.PermutationError{
			Type: token.PermutationErrorIndexOutOfBound,
		}
	}

	l.permutation(i - 1)

	return nil
}

func (l *Repeat) Permutations() int {
	return int(l.to - l.from + 1)
}

func (l *Repeat) PermutationsAll() int {
	sum := 0
	from := l.from

	if l.from == 0 {
		sum++
		from++
	}

	tokenPermutations := l.token.PermutationsAll()

	for i := from; i <= l.to; i++ {
		sum += int(math.Pow(float64(tokenPermutations), float64(i)))
	}

	return sum
}

func (l *Repeat) String() string {
	var buffer bytes.Buffer

	for _, tok := range l.value {
		buffer.WriteString(tok.String())
	}

	return buffer.String()
}

// List interface methods

func (l *Repeat) Get(i int) (token.Token, error) {
	if i < 0 || i >= len(l.value) {
		return nil, &ListError{ListErrorOutOfBound}
	}

	return l.value[i], nil
}

func (l *Repeat) Len() int {
	return len(l.value)
}

func (l *Repeat) InternalGet(i int) (token.Token, error) {
	if i != 1 {
		return nil, &ListError{ListErrorOutOfBound}
	}

	return l.token, nil
}

func (l *Repeat) InternalLen() int {
	return 1
}

func (l *Repeat) InternalLogicalRemove(tok token.Token) token.Token {
	if l.token == tok {
		return nil
	}

	return l
}

func (l *Repeat) InternalReplace(oldToken, newToken token.Token) {
	if l.token == oldToken {
		l.token = newToken

		for i := range l.value {
			l.value[i] = l.token.Clone()
		}
	}
}

// OptionalToken interface methods

func (l *Repeat) IsOptional() bool { return l.from == 0 }
func (l *Repeat) Activate() {
	if l.from != 0 {
		return
	}

	l.value = []token.Token{
		l.token.Clone(),
	}
}
func (l *Repeat) Deactivate() {
	if l.from != 0 {
		return
	}

	l.value = []token.Token{}
}
<commit_msg>add From and To methods<commit_after>package lists

import (
	"bytes"
	"math"

	"github.com/zimmski/tavor/rand"
	"github.com/zimmski/tavor/token"
)

type Repeat struct {
	from  int64
	to    int64
	token token.Token
	value []token.Token
}

func NewRepeat(tok token.Token, from, to int64) *Repeat {
	l := &Repeat{
		from:  from,
		to:    to,
		token: tok,
		value: make([]token.Token, from),
	}

	for i := range l.value {
		l.value[i] = tok.Clone()
	}

	return l
}

func (l *Repeat) From() int64 {
	return l.from
}

func (l *Repeat) To() int64 {
	return l.to
}

// Token interface methods

func (l *Repeat) Clone() token.Token {
	c := Repeat{
		from:  l.from,
		to:    l.to,
		token: l.token.Clone(),
		value: make([]token.Token, len(l.value)),
	}

	for i, tok := range l.value {
		c.value[i] = tok.Clone()
	}

	return &c
}

func (l *Repeat) Fuzz(r rand.Rand) {
	i := r.Intn(int(l.to - l.from + 1))

	l.permutation(i)
}

func (l *Repeat) FuzzAll(r rand.Rand) {
	l.Fuzz(r)

	for _, tok := range l.value {
		tok.FuzzAll(r)
	}
}

func (l *Repeat) Parse(pars *token.InternalParser, cur int) (int, []error) {
	var toks []token.Token

	for i := 1; i <= int(l.from); i++ {
		tok := l.token.Clone()

		nex, errs := tok.Parse(pars, cur)

		if len(errs) != 0 {
			return cur, errs
		}

		cur = nex
		toks = append(toks, tok)
	}

	for i := l.from; i < l.to; i++ {
		tok := l.token.Clone()

		nex, errs := tok.Parse(pars, cur)

		if len(errs) != 0 {
			break
		}

		cur = nex
		toks = append(toks, tok)
	}

	l.value = toks

	return cur, nil
}

func (l *Repeat) permutation(i int) {
	toks := make([]token.Token, i+int(l.from))

	for i := range toks {
		toks[i] = l.token.Clone()
	}

	l.value = toks
}

func (l *Repeat) Permutation(i int) error {
	permutations := l.Permutations()

	if i < 1 || i > permutations {
		return &token.PermutationError{
			Type: token.PermutationErrorIndexOutOfBound,
		}
	}

	l.permutation(i - 1)

	return nil
}

func (l *Repeat) Permutations() int {
	return int(l.to - l.from + 1)
}

func (l *Repeat) PermutationsAll() int {
	sum := 0
	from := l.from

	if l.from == 0 {
		sum++
		from++
	}

	tokenPermutations := l.token.PermutationsAll()

	for i := from; i <= l.to; i++ {
		sum += int(math.Pow(float64(tokenPermutations), float64(i)))
	}

	return sum
}

func (l *Repeat) String() string {
	var buffer bytes.Buffer

	for _, tok := range l.value {
		buffer.WriteString(tok.String())
	}

	return buffer.String()
}

// List interface methods

func (l *Repeat) Get(i int) (token.Token, error) {
	if i < 0 || i >= len(l.value) {
		return nil, &ListError{ListErrorOutOfBound}
	}

	return l.value[i], nil
}

func (l *Repeat) Len() int {
	return len(l.value)
}

func (l *Repeat) InternalGet(i int) (token.Token, error) {
	if i != 1 {
		return nil, &ListError{ListErrorOutOfBound}
	}

	return l.token, nil
}

func (l *Repeat) InternalLen() int {
	return 1
}

func (l *Repeat) InternalLogicalRemove(tok token.Token) token.Token {
	if l.token == tok {
		return nil
	}

	return l
}

func (l *Repeat) InternalReplace(oldToken, newToken token.Token) {
	if l.token == oldToken {
		l.token = newToken

		for i := range l.value {
			l.value[i] = l.token.Clone()
		}
	}
}

// OptionalToken interface methods

func (l *Repeat) IsOptional() bool { return l.from == 0 }
func (l *Repeat) Activate() {
	if l.from != 0 {
		return
	}

	l.value = []token.Token{
		l.token.Clone(),
	}
}
func (l *Repeat) Deactivate() {
	if l.from != 0 {
		return
	}

	l.value = []token.Token{}
}
<|endoftext|>


<commit_before>package config

import (
	"path/filepath"
	"time"
)

type Config struct {
	// Top level options use an anonymous struct
	BaseConfig `mapstructure:",squash"`
	// Options for services
	RPC    *RPCConfig     `mapstructure:"rpc"`
	P2P    *P2PConfig     `mapstructure:"p2p"`
	Wallet *WalletConfig  `mapstructure:"wallet"`
	Auth   *RPCAuthConfig `mapstructure:"auth"`
	Web    *WebConfig     `mapstructure:"web"`
}

// Default configurable parameters.
func DefaultConfig() *Config {
	return &Config{
		BaseConfig: DefaultBaseConfig(),
		RPC:        DefaultRPCConfig(),
		P2P:        DefaultP2PConfig(),
		Wallet:     DefaultWalletConfig(),
		Auth:       DefaultRPCAuthConfig(),
		Web:        DefaultWebConfig(),
	}
}

func TestConfig() *Config {
	return &Config{
		BaseConfig: TestBaseConfig(),
		RPC:        TestRPCConfig(),
		P2P:        TestP2PConfig(),
		Wallet:     TestWalletConfig(),
	}
}

// Set the RootDir for all Config structs
func (cfg *Config) SetRoot(root string) *Config {
	cfg.BaseConfig.RootDir = root
	cfg.RPC.RootDir = root
	cfg.P2P.RootDir = root
	return cfg
}

//-----------------------------------------------------------------------------
// BaseConfig
type BaseConfig struct {
	// The root directory for all data.
	// This should be set in viper so it can unmarshal into this struct
	RootDir string `mapstructure:"home"`

	// A JSON file containing the initial validator set and other meta data
	Genesis string `mapstructure:"genesis_file"`

	//The ID of the network to json
	ChainID string `mapstructure:"chain_id"`

	// A JSON file containing the private key to use as a validator in the consensus protocol
	PrivateKey string `mapstructure:"private_key"`

	// A custom human readable name for this node
	Moniker string `mapstructure:"moniker"`

	// TCP or UNIX socket address for the profiling server to listen on
	ProfListenAddress string `mapstructure:"prof_laddr"`

	// If this node is many blocks behind the tip of the chain, FastSync
	// allows them to catchup quickly by downloading blocks in parallel
	// and verifying their commits
	FastSync bool `mapstructure:"fast_sync"`

	Mining bool `mapstructure:"mining"`

	FilterPeers bool `mapstructure:"filter_peers"` // false

	// What indexer to use for transactions
	TxIndex string `mapstructure:"tx_index"`

	// Database backend: leveldb | memdb
	DBBackend string `mapstructure:"db_backend"`

	// Database directory
	DBPath string `mapstructure:"db_dir"`

	// Keystore directory
	KeysPath string `mapstructure:"keys_dir"`

	// remote HSM url
	HsmUrl string `mapstructure:"hsm_url"`

	ApiAddress string `mapstructure:"api_addr"`

	Time time.Time
}

// Default configurable base parameters.
func DefaultBaseConfig() BaseConfig {
	return BaseConfig{
		Genesis:           "genesis.json",
		Moniker:           "anonymous",
		ProfListenAddress: "",
		FastSync:          true,
		FilterPeers:       false,
		Mining:            false,
		TxIndex:           "kv",
		DBBackend:         "leveldb",
		DBPath:            "data",
		KeysPath:          "keystore",
		HsmUrl:            "",
	}
}

func TestBaseConfig() BaseConfig {
	conf := DefaultBaseConfig()
	conf.ChainID = "bytom_test"
	conf.FastSync = false
	conf.DBBackend = "memdb"
	return conf
}

func (b BaseConfig) GenesisFile() string {
	return rootify(b.Genesis, b.RootDir)
}

func (b BaseConfig) DBDir() string {
	return rootify(b.DBPath, b.RootDir)
}

func (b BaseConfig) KeysDir() string {
	return rootify(b.KeysPath, b.RootDir)
}

type RPCConfig struct {
	RootDir string `mapstructure:"home"`

	// TCP or UNIX socket address for the RPC server to listen on
	ListenAddress string `mapstructure:"laddr"`

	// TCP or UNIX socket address for the gRPC server to listen on
	// NOTE: This server only supports /broadcast_tx_commit
	GRPCListenAddress string `mapstructure:"grpc_laddr"`

	// Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool
	Unsafe bool `mapstructure:"unsafe"`
}

// Default configurable rpc parameters.
func DefaultRPCConfig() *RPCConfig {
	return &RPCConfig{
		ListenAddress:     "tcp://0.0.0.0:9888",
		GRPCListenAddress: "",
		Unsafe:            false,
	}
}

func TestRPCConfig() *RPCConfig {
	conf := DefaultRPCConfig()
	conf.ListenAddress = "tcp://0.0.0.0:36657"
	conf.GRPCListenAddress = "tcp://0.0.0.0:36658"
	conf.Unsafe = true
	return conf
}

//-----------------------------------------------------------------------------
// P2PConfig
type P2PConfig struct {
	RootDir          string `mapstructure:"home"`
	ListenAddress    string `mapstructure:"laddr"`
	Seeds            string `mapstructure:"seeds"`
	SkipUPNP         bool   `mapstructure:"skip_upnp"`
	AddrBook         string `mapstructure:"addr_book_file"`
	AddrBookStrict   bool   `mapstructure:"addr_book_strict"`
	PexReactor       bool   `mapstructure:"pex"`
	MaxNumPeers      int    `mapstructure:"max_num_peers"`
	HandshakeTimeout int    `mapstructure:"handshake_timeout"`
	DialTimeout      int    `mapstructure:"dial_timeout"`
}

// Default configurable p2p parameters.
func DefaultP2PConfig() *P2PConfig {
	return &P2PConfig{
		ListenAddress:    "tcp://0.0.0.0:46656",
		AddrBook:         "addrbook.json",
		AddrBookStrict:   true,
		SkipUPNP:         false,
		MaxNumPeers:      50,
		HandshakeTimeout: 30,
		DialTimeout:      3,
		PexReactor:       true,
	}
}

func TestP2PConfig() *P2PConfig {
	conf := DefaultP2PConfig()
	conf.ListenAddress = "tcp://0.0.0.0:36656"
	conf.SkipUPNP = true
	return conf
}

func (p *P2PConfig) AddrBookFile() string {
	return rootify(p.AddrBook, p.RootDir)
}

//-----------------------------------------------------------------------------
type WalletConfig struct {
	Disable bool `mapstructure:"disable"`
}

type RPCAuthConfig struct {
	Disable bool `mapstructure:"disable"`
}

type WebConfig struct {
	Closed bool `mapstructure:"closed"`
}

// Default configurable rpc's auth parameters.
func DefaultRPCAuthConfig() *RPCAuthConfig {
	return &RPCAuthConfig{
		Disable: false,
	}
}

// Default configurable web parameters.
func DefaultWebConfig() *WebConfig {
	return &WebConfig{
		Closed: false,
	}
}

// Default configurable wallet parameters.
func DefaultWalletConfig() *WalletConfig {
	return &WalletConfig{
		Disable: false,
	}
}

func TestWalletConfig() *WalletConfig {
	conf := DefaultWalletConfig()
	return conf
}

//-----------------------------------------------------------------------------
// Utils

// helper function to make config creation independent of root dir
func rootify(path, root string) string {
	if filepath.IsAbs(path) {
		return path
	}
	return filepath.Join(root, path)
}
<commit_msg>remove useless configuration<commit_after>package config

import (
	"path/filepath"
	"time"
)

type Config struct {
	// Top level options use an anonymous struct
	BaseConfig `mapstructure:",squash"`
	// Options for services
	P2P    *P2PConfig     `mapstructure:"p2p"`
	Wallet *WalletConfig  `mapstructure:"wallet"`
	Auth   *RPCAuthConfig `mapstructure:"auth"`
	Web    *WebConfig     `mapstructure:"web"`
}

// Default configurable parameters.
func DefaultConfig() *Config {
	return &Config{
		BaseConfig: DefaultBaseConfig(),
		P2P:        DefaultP2PConfig(),
		Wallet:     DefaultWalletConfig(),
		Auth:       DefaultRPCAuthConfig(),
		Web:        DefaultWebConfig(),
	}
}

// Set the RootDir for all Config structs
func (cfg *Config) SetRoot(root string) *Config {
	cfg.BaseConfig.RootDir = root
	cfg.P2P.RootDir = root
	return cfg
}

//-----------------------------------------------------------------------------
// BaseConfig
type BaseConfig struct {
	// The root directory for all data.
	// This should be set in viper so it can unmarshal into this struct
	RootDir string `mapstructure:"home"`

	// A JSON file containing the initial validator set and other meta data
	Genesis string `mapstructure:"genesis_file"`

	//The ID of the network to json
	ChainID string `mapstructure:"chain_id"`

	// A JSON file containing the private key to use as a validator in the consensus protocol
	PrivateKey string `mapstructure:"private_key"`

	// A custom human readable name for this node
	Moniker string `mapstructure:"moniker"`

	// TCP or UNIX socket address for the profiling server to listen on
	ProfListenAddress string `mapstructure:"prof_laddr"`

	// If this node is many blocks behind the tip of the chain, FastSync
	// allows them to catchup quickly by downloading blocks in parallel
	// and verifying their commits
	FastSync bool `mapstructure:"fast_sync"`

	Mining bool `mapstructure:"mining"`

	FilterPeers bool `mapstructure:"filter_peers"` // false

	// What indexer to use for transactions
	TxIndex string `mapstructure:"tx_index"`

	// Database backend: leveldb | memdb
	DBBackend string `mapstructure:"db_backend"`

	// Database directory
	DBPath string `mapstructure:"db_dir"`

	// Keystore directory
	KeysPath string `mapstructure:"keys_dir"`

	// remote HSM url
	HsmUrl string `mapstructure:"hsm_url"`

	ApiAddress string `mapstructure:"api_addr"`

	Time time.Time
}

// Default configurable base parameters.
func DefaultBaseConfig() BaseConfig {
	return BaseConfig{
		Genesis:           "genesis.json",
		Moniker:           "anonymous",
		ProfListenAddress: "",
		FastSync:          true,
		FilterPeers:       false,
		Mining:            false,
		TxIndex:           "kv",
		DBBackend:         "leveldb",
		DBPath:            "data",
		KeysPath:          "keystore",
		HsmUrl:            "",
	}
}

func (b BaseConfig) GenesisFile() string {
	return rootify(b.Genesis, b.RootDir)
}

func (b BaseConfig) DBDir() string {
	return rootify(b.DBPath, b.RootDir)
}

func (b BaseConfig) KeysDir() string {
	return rootify(b.KeysPath, b.RootDir)
}

// P2PConfig
type P2PConfig struct {
	RootDir          string `mapstructure:"home"`
	ListenAddress    string `mapstructure:"laddr"`
	Seeds            string `mapstructure:"seeds"`
	SkipUPNP         bool   `mapstructure:"skip_upnp"`
	AddrBook         string `mapstructure:"addr_book_file"`
	AddrBookStrict   bool   `mapstructure:"addr_book_strict"`
	PexReactor       bool   `mapstructure:"pex"`
	MaxNumPeers      int    `mapstructure:"max_num_peers"`
	HandshakeTimeout int    `mapstructure:"handshake_timeout"`
	DialTimeout      int    `mapstructure:"dial_timeout"`
}

// Default configurable p2p parameters.
func DefaultP2PConfig() *P2PConfig {
	return &P2PConfig{
		ListenAddress:    "tcp://0.0.0.0:46656",
		AddrBook:         "addrbook.json",
		AddrBookStrict:   true,
		SkipUPNP:         false,
		MaxNumPeers:      50,
		HandshakeTimeout: 30,
		DialTimeout:      3,
		PexReactor:       true,
	}
}

func (p *P2PConfig) AddrBookFile() string {
	return rootify(p.AddrBook, p.RootDir)
}

//-----------------------------------------------------------------------------
type WalletConfig struct {
	Disable bool `mapstructure:"disable"`
}

type RPCAuthConfig struct {
	Disable bool `mapstructure:"disable"`
}

type WebConfig struct {
	Closed bool `mapstructure:"closed"`
}

// Default configurable rpc's auth parameters.
func DefaultRPCAuthConfig() *RPCAuthConfig {
	return &RPCAuthConfig{
		Disable: false,
	}
}

// Default configurable web parameters.
func DefaultWebConfig() *WebConfig {
	return &WebConfig{
		Closed: false,
	}
}

// Default configurable wallet parameters.
func DefaultWalletConfig() *WalletConfig {
	return &WalletConfig{
		Disable: false,
	}
}

//-----------------------------------------------------------------------------
// Utils

// helper function to make config creation independent of root dir
func rootify(path, root string) string {
	if filepath.IsAbs(path) {
		return path
	}
	return filepath.Join(root, path)
}
<|endoftext|>


<commit_before>package config

import (
	"fmt"
	"io/ioutil"

	"gopkg.in/yaml.v2"

	"github.com/libopenstorage/openstorage/volume"
)

type osd struct {
	Drivers map[string]volume.DriverParams
}

type Config struct {
	Osd osd
}

const (
	DriverApiBase = "/var/lib/osd/driver/"
	PluginApiBase = "/var/lib/osd/plugin/"
	Version       = "v1"
)

var (
	cfg *Config
)

func Parse(file string) (*Config, error) {

	b, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, fmt.Errorf("Unable to read the OSD configuration file (%s): %s", file, err.Error())
	}

	err = yaml.Unmarshal(b, cfg)
	if err != nil {
		fmt.Println("Unable to parse OSD configuration: ", err)
		return nil, fmt.Errorf("Unable to parse OSD configuration: %s", err.Error())
		return nil, err
	}
	return cfg, nil
}
<commit_msg>Fix config parsing<commit_after>package config

import (
	"fmt"
	"io/ioutil"

	"gopkg.in/yaml.v2"

	"github.com/libopenstorage/openstorage/volume"
)

type osd struct {
	Drivers map[string]volume.DriverParams
}

type Config struct {
	Osd osd
}

const (
	DriverApiBase = "/var/lib/osd/driver/"
	PluginApiBase = "/var/lib/osd/plugin/"
	Version       = "v1"
)

var (
	cfg Config
)

func Parse(file string) (*Config, error) {

	b, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, fmt.Errorf("Unable to read the OSD configuration file (%s): %s", file, err.Error())
	}

	err = yaml.Unmarshal(b, &cfg)
	if err != nil {
		fmt.Println("Unable to parse OSD configuration: ", err)
		return nil, fmt.Errorf("Unable to parse OSD configuration: %s", err.Error())
		return nil, err
	}
	return &cfg, nil
}
<|endoftext|>