<commit_before>package main

import (
	"encoding/json"
	"html/template"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
	"sync"
)

var staticConfig *Config
var configLock = new(sync.RWMutex)

type Config struct {
	Global    GlobalSection
	Redirects []RedirectSection
	Server    []ServerSection
	Indexes   []IndexSection
}

//var templates = template.Must(template.ParseFiles("/var/wiki-backend/wiki.html"))
//template.New("allTemplates")
var allTemplates = template.New("allTemplates")
var templateLock = new(sync.RWMutex)

type GlobalSection struct {
	Address     string
	Port        string
	Hostname    string
	TemplateDir string
	CertFile    string
	KeyFile     string
}

type RedirectSection struct {
	Requested string
	Target    string
	Code      int
}

type IndexSection struct {
	WatchDirs      map[string]string // physical -> URI Location that we will be watching for updates
	WatchExtension string            // file extensions that we will watch for within that dir
	IndexPath      string            //location to store the index
	IndexType      string            // type of index - likely "en"
	IndexName      string            // name of the index
	Restricted     []string          // Tags to restrict indexing on
}

type ServerSection struct {
	Path       string   // filesystem path to serve out
	Prefix     string   // Web URL Prefix - alternatively the prefix for a search handler
	Default    string   // Default page to serve if empty URI - alternatively the facet to list against
	Template   string   // Template file to build the response from
	ServerType string   // markdown, raw, search, or facet to denote the type of Server handle
	TopicURL   string   // URI prefix to redirect to topic pages
	Restricted []string // list of restricts - extensions for raw, topics for markdown
}

func GetConfig() *Config {
	configLock.RLock()
	defer configLock.RUnlock()
	return staticConfig
}

func LoadConfig(configFile string) error {

	if configFile == "" {
		// log.Println("no configuration file specified, using ./config.json")
		// return an empty config file
		configFile = "config.json"
	}

	// have to read in the line into a byte[] array
	fileContents, err := ioutil.ReadFile(configFile)
	if err != nil {
		return &Error{Code: ErrReadConfig, innerError: err, value: configFile}
	}

	// UnMarshal the config file that was read in
	temp := new(Config)

	err = json.Unmarshal(fileContents, temp)
	//Make sure you were able to read it in
	if err != nil {
		return &Error{Code: ErrParseConfig, value: temp, innerError: err}
	}

	CleanConfig(temp)

	// log.Println(temp.Indexes)

	configLock.Lock()
	staticConfig = temp
	configLock.Unlock()

	return nil
}

func CleanConfig(config *Config) {
	if !strings.HasSuffix(config.Global.TemplateDir, string(os.PathSeparator)) {
		config.Global.TemplateDir = config.Global.TemplateDir + string(os.PathSeparator)
	}
	for _, indexSection := range config.Indexes {
		for origDirPath, origWebPath := range indexSection.WatchDirs {
			newDirPath := strings.TrimSuffix(origDirPath, string(os.PathSeparator))
			newWebPath := strings.TrimSuffix(origWebPath, "/")
			if newDirPath == "" {
				newDirPath = string(os.PathSeparator)
			}
			if newWebPath == "" {
				newWebPath = "/"
			}
			if newDirPath != origDirPath || newWebPath != origWebPath {
				delete(indexSection.WatchDirs, origDirPath)
				indexSection.WatchDirs[newDirPath] = newWebPath
			}
		}
	}
	for _, serverSection := range config.Server {
		if serverSection.Path != string(os.PathSeparator) {
			serverSection.Path = strings.TrimSuffix(serverSection.Path, string(os.PathSeparator))
		}
		if serverSection.Prefix != "/" {
			serverSection.Prefix = strings.TrimSuffix(serverSection.Prefix, "/")
		}
	}
}

func RenderTemplate(responsePipe http.ResponseWriter, templateName string,
	data interface{}) error {
	templateLock.RLock()
	defer templateLock.RUnlock()

	return allTemplates.ExecuteTemplate(responsePipe, templateName, data)
}

func ParseTemplates(globalConfig GlobalSection) error {
	// log.Printf("Parsing templates in [%q]", globalConfig.TemplateDir)
	newTemplate, err := template.ParseGlob(globalConfig.TemplateDir + "*")
	if err != nil {
		return &Error{Code: ErrParseTemplates, innerError: err}
	}

	// loadedTemplates := newTemplate.Templates()
	// for _, individualTemplate := range loadedTemplates {
	// 	log.Printf("Loaded template %s ", individualTemplate.Name())
	// }

	templateLock.Lock()
	defer templateLock.Unlock()
	allTemplates = newTemplate
	return nil
}
<commit_msg>removed the global config section<commit_after>package main

import (
	"encoding/json"
	"html/template"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
	"sync"
)

var staticConfig *Config
var configLock = new(sync.RWMutex)

//var templates = template.Must(template.ParseFiles("/var/wiki-backend/wiki.html"))
//template.New("allTemplates")
var allTemplates = template.New("allTemplates")
var templateLock = new(sync.RWMutex)

type GlobalSection struct {
	Address     string
	Port        string
	Hostname    string
	TemplateDir string
	CertFile    string
	KeyFile     string
	Indexes     []IndexSection
}

type RedirectSection struct {
	Requested string
	Target    string
	Code      int
}

type IndexSection struct {
	WatchDirs      map[string]string // physical -> URI Location that we will be watching for updates
	WatchExtension string            // file extensions that we will watch for within that dir
	IndexPath      string            //location to store the index
	IndexType      string            // type of index - likely "en"
	IndexName      string            // name of the index
	Restricted     []string          // Tags to restrict indexing on
	Handlers       []ServerSection
	Redirects      []RedirectSection
}

type ServerSection struct {
	Path       string   // filesystem path to serve out
	Prefix     string   // Web URL Prefix - alternatively the prefix for a search handler
	Default    string   // Default page to serve if empty URI - alternatively the facet to list against
	Template   string   // Template file to build the response from
	ServerType string   // markdown, raw, search, or facet to denote the type of Server handle
	TopicURL   string   // URI prefix to redirect to topic pages
	Restricted []string // list of restricts - extensions for raw, topics for markdown
}

func GetConfig() *Config {
	configLock.RLock()
	defer configLock.RUnlock()
	return staticConfig
}

func LoadConfig(configFile string) error {

	if configFile == "" {
		// log.Println("no configuration file specified, using ./config.json")
		// return an empty config file
		configFile = "config.json"
	}

	// have to read in the line into a byte[] array
	fileContents, err := ioutil.ReadFile(configFile)
	if err != nil {
		return &Error{Code: ErrReadConfig, innerError: err, value: configFile}
	}

	// UnMarshal the config file that was read in
	temp := new(Config)

	err = json.Unmarshal(fileContents, temp)
	//Make sure you were able to read it in
	if err != nil {
		return &Error{Code: ErrParseConfig, value: temp, innerError: err}
	}

	CleanConfig(temp)

	// log.Println(temp.Indexes)

	configLock.Lock()
	staticConfig = temp
	configLock.Unlock()

	return nil
}

func CleanConfig(config *Config) {
	if !strings.HasSuffix(config.Global.TemplateDir, string(os.PathSeparator)) {
		config.Global.TemplateDir = config.Global.TemplateDir + string(os.PathSeparator)
	}
	for _, indexSection := range config.Indexes {
		for origDirPath, origWebPath := range indexSection.WatchDirs {
			newDirPath := strings.TrimSuffix(origDirPath, string(os.PathSeparator))
			newWebPath := strings.TrimSuffix(origWebPath, "/")
			if newDirPath == "" {
				newDirPath = string(os.PathSeparator)
			}
			if newWebPath == "" {
				newWebPath = "/"
			}
			if newDirPath != origDirPath || newWebPath != origWebPath {
				delete(indexSection.WatchDirs, origDirPath)
				indexSection.WatchDirs[newDirPath] = newWebPath
			}
		}
		for _, serverSection := range config.Server {
			if serverSection.Path != string(os.PathSeparator) {
				serverSection.Path = strings.TrimSuffix(serverSection.Path, string(os.PathSeparator))
			}
			if serverSection.Prefix != "/" {
				serverSection.Prefix = strings.TrimSuffix(serverSection.Prefix, "/")
			}
		}
	}
}

func RenderTemplate(responsePipe http.ResponseWriter, templateName string,
	data interface{}) error {
	templateLock.RLock()
	defer templateLock.RUnlock()

	return allTemplates.ExecuteTemplate(responsePipe, templateName, data)
}

func ParseTemplates(globalConfig GlobalSection) error {
	// log.Printf("Parsing templates in [%q]", globalConfig.TemplateDir)
	newTemplate, err := template.ParseGlob(globalConfig.TemplateDir + "*")
	if err != nil {
		return &Error{Code: ErrParseTemplates, innerError: err}
	}

	templateLock.Lock()
	defer templateLock.Unlock()
	allTemplates = newTemplate
	return nil
}
<|endoftext|>


<commit_before>package adapter

import (
	"io/ioutil"
	"os"
	"strconv"
	"strings"

	"github.com/gorilla/sessions"
	"gopkg.in/yaml.v2"
)

// Config is a configration for go-nginx-oauth2-adapter.
type Config struct {
	Address            string                            `yaml:"address" json:"address"`
	Secrets            []*string                         `yaml:"secrets" json:"secrets"`
	SessionName        string                            `yaml:"session_name" json:"session_name"`
	Providers          map[string]map[string]interface{} `yaml:"providers" json:"providers"`
	AppRefreshInterval string                            `yaml:"app_refresh_interval" json:"app_refresh_interval"`

	// set with -configtest option.
	ConfigTest bool `yaml:"-" json:"-"`

	// Fields are a subset of http.Cookie fields.
	Cookie *CookieConfig `yaml:"cookie" json:"cookie"`
}

// CookieConfig is a configration for the cookie of HTTP.
type CookieConfig struct {
	Path   string `yaml:"path" json:"path"`
	Domain string `yaml:"domain" json:"domain"`
	// MaxAge=0 means no 'Max-Age' attribute specified.
	// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'.
	// MaxAge>0 means Max-Age attribute present and given in seconds.
	MaxAge   int  `yaml:"max_age" json:"max_age"`
	Secure   bool `yaml:"secure" json:"secure"`
	HTTPOnly bool `yaml:"http_only" json:"http_only"`
}

// NewConfig returns a new config.
func NewConfig() *Config {
	return &Config{
		Address:            ":18081",
		Secrets:            nil,
		SessionName:        "go-nginx-oauth2-session",
		Providers:          map[string]map[string]interface{}{},
		AppRefreshInterval: "24h",
		Cookie: &CookieConfig{
			Path:   "/",
			MaxAge: 60 * 60 * 24 * 3,
		},
	}
}

// LoadYaml loads the config from yaml file.
func (c *Config) LoadYaml(filename string) error {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return err
	}

	return yaml.Unmarshal(data, c)
}

// LoadEnv loads the config from the environment values.
func (c *Config) LoadEnv() error {
	if v := os.Getenv("NGX_OMNIAUTH_SESSION_COOKIE_TIMEOUT"); v != "" {
		i, err := strconv.Atoi(v)
		if err != nil {
			return err
		}
		c.Cookie.MaxAge = i
	}

	if v := os.Getenv("NGX_OMNIAUTH_SESSION_COOKIE_SECURE"); v != "" {
		b, err := strconv.ParseBool(v)
		if err != nil {
			return err
		}
		c.Cookie.Secure = b
	}

	if v := os.Getenv("NGX_OMNIAUTH_SESSION_COOKIE_HTTP_ONLY"); v != "" {
		b, err := strconv.ParseBool(v)
		if err != nil {
			return err
		}
		c.Cookie.HTTPOnly = b
	}

	if v := os.Getenv("NGX_OMNIAUTH_SESSION_SECRET"); v != "" {
		for _, v := range strings.Split(v, ",") {
			c.Secrets = append(c.Secrets, &v)
		}
	}

	if v := os.Getenv("NGX_OMNIAUTH_SESSION_COOKIE_NAME"); v != "" {
		c.SessionName = v
	}

	if v := os.Getenv("NGX_OMNIAUTH_APP_REFRESH_INTERVAL"); v != "" {
		c.AppRefreshInterval = v
	}

	if v := os.Getenv("NGX_OMNIAUTH_ADDRESS"); v != "" {
		c.Address = v
	}

	return nil
}

// Options returns the sesseion config.
func (c *CookieConfig) Options() *sessions.Options {
	if c == nil {
		return &sessions.Options{}
	}
	return &sessions.Options{
		Path:     c.Path,
		Domain:   c.Domain,
		MaxAge:   c.MaxAge,
		Secure:   c.Secure,
		HttpOnly: c.HTTPOnly,
	}
}
<commit_msg>fix scope of v<commit_after>package adapter

import (
	"io/ioutil"
	"os"
	"strconv"
	"strings"

	"github.com/gorilla/sessions"
	"gopkg.in/yaml.v2"
)

// Config is a configration for go-nginx-oauth2-adapter.
type Config struct {
	Address            string                            `yaml:"address" json:"address"`
	Secrets            []*string                         `yaml:"secrets" json:"secrets"`
	SessionName        string                            `yaml:"session_name" json:"session_name"`
	Providers          map[string]map[string]interface{} `yaml:"providers" json:"providers"`
	AppRefreshInterval string                            `yaml:"app_refresh_interval" json:"app_refresh_interval"`

	// set with -configtest option.
	ConfigTest bool `yaml:"-" json:"-"`

	// Fields are a subset of http.Cookie fields.
	Cookie *CookieConfig `yaml:"cookie" json:"cookie"`
}

// CookieConfig is a configration for the cookie of HTTP.
type CookieConfig struct {
	Path   string `yaml:"path" json:"path"`
	Domain string `yaml:"domain" json:"domain"`
	// MaxAge=0 means no 'Max-Age' attribute specified.
	// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'.
	// MaxAge>0 means Max-Age attribute present and given in seconds.
	MaxAge   int  `yaml:"max_age" json:"max_age"`
	Secure   bool `yaml:"secure" json:"secure"`
	HTTPOnly bool `yaml:"http_only" json:"http_only"`
}

// NewConfig returns a new config.
func NewConfig() *Config {
	return &Config{
		Address:            ":18081",
		Secrets:            nil,
		SessionName:        "go-nginx-oauth2-session",
		Providers:          map[string]map[string]interface{}{},
		AppRefreshInterval: "24h",
		Cookie: &CookieConfig{
			Path:   "/",
			MaxAge: 60 * 60 * 24 * 3,
		},
	}
}

// LoadYaml loads the config from yaml file.
func (c *Config) LoadYaml(filename string) error {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return err
	}

	return yaml.Unmarshal(data, c)
}

// LoadEnv loads the config from the environment values.
func (c *Config) LoadEnv() error {
	if v := os.Getenv("NGX_OMNIAUTH_SESSION_COOKIE_TIMEOUT"); v != "" {
		i, err := strconv.Atoi(v)
		if err != nil {
			return err
		}
		c.Cookie.MaxAge = i
	}

	if v := os.Getenv("NGX_OMNIAUTH_SESSION_COOKIE_SECURE"); v != "" {
		b, err := strconv.ParseBool(v)
		if err != nil {
			return err
		}
		c.Cookie.Secure = b
	}

	if v := os.Getenv("NGX_OMNIAUTH_SESSION_COOKIE_HTTP_ONLY"); v != "" {
		b, err := strconv.ParseBool(v)
		if err != nil {
			return err
		}
		c.Cookie.HTTPOnly = b
	}

	if v := os.Getenv("NGX_OMNIAUTH_SESSION_SECRET"); v != "" {
		for _, v := range strings.Split(v, ",") {
			v := v
			c.Secrets = append(c.Secrets, &v)
		}
	}

	if v := os.Getenv("NGX_OMNIAUTH_SESSION_COOKIE_NAME"); v != "" {
		c.SessionName = v
	}

	if v := os.Getenv("NGX_OMNIAUTH_APP_REFRESH_INTERVAL"); v != "" {
		c.AppRefreshInterval = v
	}

	if v := os.Getenv("NGX_OMNIAUTH_ADDRESS"); v != "" {
		c.Address = v
	}

	return nil
}

// Options returns the sesseion config.
func (c *CookieConfig) Options() *sessions.Options {
	if c == nil {
		return &sessions.Options{}
	}
	return &sessions.Options{
		Path:     c.Path,
		Domain:   c.Domain,
		MaxAge:   c.MaxAge,
		Secure:   c.Secure,
		HttpOnly: c.HTTPOnly,
	}
}
<|endoftext|>


<commit_before>// Copyright 2012 GAEGo Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
Package config provides persisted configuration maps that can be set
and retrieved using a unique key.

Each Config is stored in memory, memcache, and the datastore. This allows
Config settings to be shared between instances, while at the same time
elimating the cost associated with retrieving directly form the datastore.

Example Usage:

Set the config

	c := appengine.Context(r)
	appMap := map[string]string{
		"Title": "Storeski"
	}
	appConfig, err := config.GetOrInsert(c, "app", appMap)

Get the config in another package

	appConfig, err := config.Get(c, "app")
	appTitle := appConfig.Values"Title"] // "Storeski"

Edit and save the config

	appConfig.Values["Title"] = "Changed"
  err := appConfig.Put(c)
	appConfig2, err := config.Get(c, "app")
  appTitle := appConfig2.Values["Title"] // "Changed"

*/
package config

// TODO(kylefinley) move the JSON encoding of invalid datastore types
// to ds.

import (
	"appengine"
	"appengine/datastore"
	"bytes"
	"encoding/gob"
	"github.com/gaego/ds"
)

func init() {
	// Store Config entities in datastore, memcache and memory.
	ds.Register("Config", true, true, true)
}

// Config is the struct that is stored. The map[string]string{}
// is gob encoded before being passed to ds.
type Config struct {
	Key       *datastore.Key `datastore:"-"`
	ValuesGob []byte
	Values    map[string]string `datastore:"-"`
}

// SetKey set the Key property to a datastore.Key using the passed key
// as the StringID
func (cnfg *Config) SetKey(c appengine.Context, key string) {
	cnfg.Key = datastore.NewKey(c, "Config", key, 0, nil)
	return
}

// Encode is called prior to save. Any fields that need to be updated
// prior to save are updated here.
func (cnfg *Config) Encode() error {
	var b bytes.Buffer
	enc := gob.NewEncoder(&b)
	err := enc.Encode(cnfg.Values)
	cnfg.ValuesGob = b.Bytes()
	return err
}

// Decode is called after the entity has been retrieved from the the ds.
func (cnfg *Config) Decode() error {
	b := bytes.NewBuffer(cnfg.ValuesGob)
	dec := gob.NewDecoder(b)
	err := dec.Decode(&cnfg.Values)
	return err
}

// Put encodes the Values and saves the Config to the store.
func (cnfg *Config) Put(c appengine.Context) (err error) {
	if err = cnfg.Encode(); err != nil {
		return
	}
	key, err := ds.Put(c, cnfg.Key, cnfg)
	cnfg.Key = key
	return
}

// Get retieves a Config using the string key. If Config is not found
// it returns ds/error.ErrNoSuchEntity.
func Get(c appengine.Context, key string) (cnfg *Config, err error) {

	cnfg = new(Config)
	cnfg.SetKey(c, key)
	err = ds.Get(c, cnfg.Key, cnfg)
	if err != nil {
		return
	}
	err = cnfg.Decode()
	return
}

// GetOrInsert takes takes a key and map. If the key belongs to a previously
// saved Config it is returned; Otherwise the map is saved.
func GetOrInsert(c appengine.Context, key string,
	m map[string]string) (cnfg *Config, err error) {

	cnfg, err = Get(c, key)
	if err == nil {
		return
	}
	cnfg = new(Config)
	cnfg.Values = m
	cnfg.SetKey(c, key)
	err = cnfg.Put(c)
	return
}
<commit_msg>encode() and decode() should be private<commit_after>// Copyright 2012 GAEGo Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
Package config provides persisted configuration maps that can be set
and retrieved using a unique key.

Each Config is stored in memory, memcache, and the datastore. This allows
Config settings to be shared between instances, while at the same time
elimating the cost associated with retrieving directly form the datastore.

Example Usage:

Set the config

	c := appengine.Context(r)
	appMap := map[string]string{
		"Title": "Storeski"
	}
	appConfig, err := config.GetOrInsert(c, "app", appMap)

Get the config in another package

	appConfig, err := config.Get(c, "app")
	appTitle := appConfig.Values"Title"] // "Storeski"

Edit and save the config

	appConfig.Values["Title"] = "Changed"
  err := appConfig.Put(c)
	appConfig2, err := config.Get(c, "app")
  appTitle := appConfig2.Values["Title"] // "Changed"

*/
package config

// TODO(kylefinley) move the JSON encoding of invalid datastore types
// to ds.

import (
	"appengine"
	"appengine/datastore"
	"bytes"
	"encoding/gob"
	"github.com/gaego/ds"
)

func init() {
	// Store Config entities in datastore, memcache and memory.
	ds.Register("Config", true, true, true)
}

// Config is the struct that is stored. The map[string]string{}
// is gob encoded before being passed to ds.
type Config struct {
	Key       *datastore.Key `datastore:"-"`
	ValuesGob []byte
	Values    map[string]string `datastore:"-"`
}

// SetKey set the Key property to a datastore.Key using the passed key
// as the StringID
func (cnfg *Config) SetKey(c appengine.Context, key string) {
	cnfg.Key = datastore.NewKey(c, "Config", key, 0, nil)
	return
}

// encode is called prior to save. Any fields that need to be updated
// prior to save are updated here.
func (cnfg *Config) encode() error {
	var b bytes.Buffer
	enc := gob.NewEncoder(&b)
	err := enc.Encode(cnfg.Values)
	cnfg.ValuesGob = b.Bytes()
	return err
}

// decode is called after the entity has been retrieved from the the ds.
func (cnfg *Config) decode() error {
	b := bytes.NewBuffer(cnfg.ValuesGob)
	dec := gob.NewDecoder(b)
	err := dec.Decode(&cnfg.Values)
	return err
}

// Put encodes the Values and saves the Config to the store.
func (cnfg *Config) Put(c appengine.Context) (err error) {
	if err = cnfg.encode(); err != nil {
		return
	}
	key, err := ds.Put(c, cnfg.Key, cnfg)
	cnfg.Key = key
	return
}

// Get retieves a Config using the string key. If Config is not found
// it returns ds/error.ErrNoSuchEntity.
func Get(c appengine.Context, key string) (cnfg *Config, err error) {

	cnfg = new(Config)
	cnfg.SetKey(c, key)
	err = ds.Get(c, cnfg.Key, cnfg)
	if err != nil {
		return
	}
	err = cnfg.decode()
	return
}

// GetOrInsert takes takes a key and map. If the key belongs to a previously
// saved Config it is returned; Otherwise the map is saved.
func GetOrInsert(c appengine.Context, key string,
	m map[string]string) (cnfg *Config, err error) {

	cnfg, err = Get(c, key)
	if err == nil {
		return
	}
	cnfg = new(Config)
	cnfg.Values = m
	cnfg.SetKey(c, key)
	err = cnfg.Put(c)
	return
}
<|endoftext|>


<commit_before>/*
Copyright IBM Corp 2016 All Rights Reserved.

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

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

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

package main

import (
	"errors"
	"fmt"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

// ============================================================================================================================
// Main
// ============================================================================================================================
func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	return nil, nil
}

// Invoke is our entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)

	// Handle different functions
	if function == "init" {													//initialize the chaincode state, used as reset
		return t.Init(stub, "init", args)
	}
	if function == "say_hello" {
		fmt.Printf("Hey")
		return nil, nil
	}
	fmt.Println("invoke did not find func: " + function)					//error

	return nil, errors.New("Received unknown function invocation: " + function)
}

// Query is our entry point for queries
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)

	// Handle different functions
	if function == "dummy_query" {											//read a variable
		fmt.Println("hi there " + function)						//error
		return nil, nil;
	}
	fmt.Println("query did not find func: " + function)						//error

	return nil, errors.New("Received unknown function query: " + function)
}
<commit_msg>added read and write functions<commit_after>/*
Copyright IBM Corp 2016 All Rights Reserved.

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

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

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

package main

import (
	"errors"
	"fmt"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

// ============================================================================================================================
// Main
// ============================================================================================================================
func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}
	err := stub.PutState("hello_world", []byte(args[0]))
	if err != nil {
		return nil, err
	}
	return nil, nil
}

// Invoke is our entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)

	// Handle different functions
	if function == "init" { //initialize the chaincode state, used as reset
		return t.Init(stub, "init", args)
	}
	fmt.Println("invoke did not find func: " + function) //error

	if function == "write" {
		return t.write(stub, args)
	}

	return nil, errors.New("Received unknown function invocation: " + function)
}

func (t *SimpleChaincode) write(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	if len(args) != 2 {
		return nil, errors.New("Wrong number of arguments, should be 2")
	}
	var name, value = args[0], args[1]
	err := stub.PutState(name, []byte(value))
	if err != nil {
		return nil, err
	}
	return nil, nil
}

// Query is our entry point for queries
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)

	// Handle different functions
	if function == "read" {
		t.read(stub, args)
	}
	fmt.Println("query did not find func: " + function)

	return nil, errors.New("Received unknown function query")
}

func (t *SimpleChaincode) read(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	var name, jsonResp string
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the var to query")
	}

	name = args[0]
	valAsbytes, err := stub.GetState(name)
	if err != nil {
		jsonResp = "{\"Error\":\"Failed to get state for " + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	return valAsbytes, nil
}
<|endoftext|>


<commit_before>package main

/* import (
	"errors"
	"fmt"

	"github.com/hyperledger/fabric/core/chaincode/shim"
) */

import (
	"errors"
	"fmt"
	//"strconv"
	//"strings"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	"encoding/json"
	//"regexp"
	//"time"
	"crypto/rand"
	//"io"
)

var logger = shim.NewLogger("CLDChaincode")

// Participant
const	SHIPPER      =  		"shipper"
const	LOGISTIC_PROVIDER   =  	"logistic_provider"
const	INSURENCE_COMPANY = 	"insurence_company"

// Status
const CREATED = "CRIADO"
const CANCEL = "cancel"
const SUCESS = "success"
const DISPATCHED = "dispatched"

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

type Volume struct {
	TrackId									string `json: trackId`
	Owner									string `json: owner`
	Shipper									string `json: owner`
	Status									string `json: status`
	LogisticProvider						string `json: logisticProvider`
}

func main() {
	fmt.Println("Start Contract")

	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	return nil, nil
}

// Invoke is our entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args [] string) ([]byte, error) {
    fmt.Println("invoke is running " + function)

    // Handle different functions
    if function == "init" {
        return t.Init(stub, "init", args)
	} else if function == "CreateVolume" {
		return t.CreateVolume(stub, args[0])
	} else if function == "shipperToLogisticProvider" {
        return t.ShipperToLogisticProvider(stub, args)
    } /*else if function == "LogisticProviderToCustomer" {
		return t.LogisticProviderToCustomer(stub, args)
	} else if function == "LogisticProviderToLogisticProvider" {
		return t.LogisticProviderToLogisticProvider(stub, args)
	} else if function == "LogisticProviderToShipper" {
		return t.LogisticProviderToShipper(stub, args)
	} */

    fmt.Println("invoke did not find func: " + function)
	logger.Debug("invoke did not find func: ", function)

    return nil, errors.New("Received unknown function invocation")
}

func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	logger.Debug("query function: ", function)
	fmt.Println(args)

	if function == "get_volumes" {
		return t.get_volumes(stub, args)
	}

	return nil, errors.New("Received unknown function invocation " + function)
}

// Functions to Write
func (t *SimpleChaincode) CreateVolume(stub shim.ChaincodeStubInterface, shipper string) ([]byte, error) {
	var v Volume

	var err error
	var bytes []byte

	v.TrackId = GenerateRandomString(10)
	v.Owner = "SHIPPER"
	v.Shipper = shipper
	v.Status = CREATED

 	fmt.Println("[Volume]: " + v.TrackId)

	bytes, err = json.Marshal(v)

	err = stub.PutState(v.TrackId, bytes)

	if err != nil { return nil, errors.New("Unable to put the state") }

	return nil, nil
}

func (t *SimpleChaincode) ShipperToLogisticProvider(stub shim.ChaincodeStubInterface, args [] string) ([]byte, error) {
	fmt.Println("shipper to logistic provider running");

	var trackId = args[0];
	var logisticProvider = args[1]
	var v Volume

	fmt.Println("shipper to logistic provider: get state");

	bytes, err := stub.GetState(trackId)
	if err != nil { return nil, errors.New("could not possible do getState ") }

	err = json.Unmarshal(bytes, &v)
	if err != nil { return nil, errors.New("could not possible do unmarshal ") }

	fmt.Println("shipper to logistic provider: got state");

	v.Status = DISPATCHED
	v.LogisticProvider = logisticProvider

	bytes, err = json.Marshal(v)
	if err != nil { return nil, errors.New("could not possible do marshal ") }

	err = stub.PutState(trackId, bytes)

	if err != nil { return nil, errors.New("could not possible do putState ") }

	return nil, nil
}

func GenerateRandomString(n int) (string) {
    const letters = "0123456789"
    bytes := GenerateRandomBytes(n)

    for i, b := range bytes {
        bytes[i] = letters[b%byte(len(letters))]
    }

    return (string(bytes))
}

func GenerateRandomBytes(n int) ([]byte) {
    b := make([]byte, n)
    _, err := rand.Read(b)

    if err != nil {
        return nil
    }

    return b
}

func (t *SimpleChaincode) get_volumes(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	//select range
	resultsIterator, err := stub.RangeQueryState("0", "9999999999")

	if err != nil {
		return nil, errors.New("[IP][Query] Unknown error")
	}

	field := args[0]
	value := args[1]
	fmt.Println(field)
	fmt.Println(value)
	// logisticProviderId := args[1]
	// pendingOrder, err := strconv.ParseBool(args[2])
	// findAll, err := strconv.ParseBool(args[3])

	hasResult := false

	defer resultsIterator.Close()

	result := "{\"volumes\": ["

	for resultsIterator.HasNext() {
		queryKeyAsStr, queryValAsBytes, err := resultsIterator.Next()

		fmt.Println("[IP][Query] hack: " + queryKeyAsStr)

		if err != nil {
			return nil, errors.New("[IP][Query] Unknown error")
		}

		var volume Volume
		json.Unmarshal(queryValAsBytes, &volume)
		fmt.Println(string(queryValAsBytes));

		if field == "trackerId" {
			if volume.TrackId == value {
				result += string(queryValAsBytes) + ","
				hasResult = true
			}
		} else if field == "shipper" {
			if volume.Shipper == value && volums.Status == "CRIADO" {
				result += string(queryValAsBytes) + ","
				hasResult = true
			}
		} else if field == "logistic_provider" {
			if volume.LogisticProvider == value {
				result += string(queryValAsBytes) + ","
				hasResult = true
			}
		} else {
			result += string(queryValAsBytes) + ","
			hasResult = true
		}

		// clientIdOk := clientId == "-1" || volume.ClientId == clientId
		// logisticProviderIdOk := logisticProviderId == "-1" || volume.LogisticProviderId == logisticProviderId

		// var findPendingOk bool

		// if pendingOrder {
		// 	findPendingOk = (volume.LogisticProviderFinalShippingCost == 0)
		// } else {
		// 	findPendingOk = (volume.LogisticProviderFinalShippingCost != 0)
		// }

		// fmt.Println("[IP][Query] ClientId: " + clientId + " | LogisticProviderId: " + logisticProviderId + " | PendingOrder: " + strconv.FormatBool(pendingOrder) + " | ClientIdOk: " + strconv.FormatBool(clientIdOk) + " | LogisticProviderIdOk: " + strconv.FormatBool(logisticProviderIdOk) + " | FindPendingOk: " + strconv.FormatBool(findPendingOk) + " | FindAll: " + strconv.FormatBool(findAll))
	}

	if hasResult {
		result = result[:len(result)-1] + "]}"
	} else {
		result = result + "]}"
	}

	return []byte(result), nil
}

func (t *SimpleChaincode) get_volume(stub shim.ChaincodeStubInterface, trackerId string) (Volume, error) {
	//select range
	resultsIterator, err := stub.RangeQueryState("0", "9999999999")
    var volume Volume
	if err != nil {
		return volume, errors.New("[IP][Query] Unknown error")
	}

	defer resultsIterator.Close()

	for resultsIterator.HasNext() {
		queryKeyAsStr, queryValAsBytes, err := resultsIterator.Next()

		fmt.Println("[IP][Query] hack: " + queryKeyAsStr)

		if err != nil {
			return volume, errors.New("[IP][Query] Unknown error")
		}

		json.Unmarshal(queryValAsBytes, &volume)
		fmt.Println(string(queryValAsBytes));

		return volume, nil
	}

	return volume, nil
}<commit_msg>Query<commit_after>package main

/* import (
	"errors"
	"fmt"

	"github.com/hyperledger/fabric/core/chaincode/shim"
) */

import (
	"errors"
	"fmt"
	//"strconv"
	//"strings"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	"encoding/json"
	//"regexp"
	//"time"
	"crypto/rand"
	//"io"
)

var logger = shim.NewLogger("CLDChaincode")

// Participant
const	SHIPPER      =  		"shipper"
const	LOGISTIC_PROVIDER   =  	"logistic_provider"
const	INSURENCE_COMPANY = 	"insurence_company"

// Status
const CREATED = "CRIADO"
const CANCEL = "cancel"
const SUCESS = "success"
const DISPATCHED = "dispatched"

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

type Volume struct {
	TrackId									string `json: trackId`
	Owner									string `json: owner`
	Shipper									string `json: owner`
	Status									string `json: status`
	LogisticProvider						string `json: logisticProvider`
}

func main() {
	fmt.Println("Start Contract")

	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	return nil, nil
}

// Invoke is our entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args [] string) ([]byte, error) {
    fmt.Println("invoke is running " + function)

    // Handle different functions
    if function == "init" {
        return t.Init(stub, "init", args)
	} else if function == "CreateVolume" {
		return t.CreateVolume(stub, args[0])
	} else if function == "shipperToLogisticProvider" {
        return t.ShipperToLogisticProvider(stub, args)
    } /*else if function == "LogisticProviderToCustomer" {
		return t.LogisticProviderToCustomer(stub, args)
	} else if function == "LogisticProviderToLogisticProvider" {
		return t.LogisticProviderToLogisticProvider(stub, args)
	} else if function == "LogisticProviderToShipper" {
		return t.LogisticProviderToShipper(stub, args)
	} */

    fmt.Println("invoke did not find func: " + function)
	logger.Debug("invoke did not find func: ", function)

    return nil, errors.New("Received unknown function invocation")
}

func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	logger.Debug("query function: ", function)
	fmt.Println(args)

	if function == "get_volumes" {
		return t.get_volumes(stub, args)
	}

	return nil, errors.New("Received unknown function invocation " + function)
}

// Functions to Write
func (t *SimpleChaincode) CreateVolume(stub shim.ChaincodeStubInterface, shipper string) ([]byte, error) {
	var v Volume

	var err error
	var bytes []byte

	v.TrackId = GenerateRandomString(10)
	v.Owner = "SHIPPER"
	v.Shipper = shipper
	v.Status = CREATED

 	fmt.Println("[Volume]: " + v.TrackId)

	bytes, err = json.Marshal(v)

	err = stub.PutState(v.TrackId, bytes)

	if err != nil { return nil, errors.New("Unable to put the state") }

	return nil, nil
}

func (t *SimpleChaincode) ShipperToLogisticProvider(stub shim.ChaincodeStubInterface, args [] string) ([]byte, error) {
	fmt.Println("shipper to logistic provider running");

	var trackId = args[0];
	var logisticProvider = args[1]
	var v Volume

	fmt.Println("shipper to logistic provider: get state");

	bytes, err := stub.GetState(trackId)
	if err != nil { return nil, errors.New("could not possible do getState ") }

	err = json.Unmarshal(bytes, &v)
	if err != nil { return nil, errors.New("could not possible do unmarshal ") }

	fmt.Println("shipper to logistic provider: got state");

	v.Status = DISPATCHED
	v.LogisticProvider = logisticProvider

	bytes, err = json.Marshal(v)
	if err != nil { return nil, errors.New("could not possible do marshal ") }

	err = stub.PutState(trackId, bytes)

	if err != nil { return nil, errors.New("could not possible do putState ") }

	return nil, nil
}

func GenerateRandomString(n int) (string) {
    const letters = "0123456789"
    bytes := GenerateRandomBytes(n)

    for i, b := range bytes {
        bytes[i] = letters[b%byte(len(letters))]
    }

    return (string(bytes))
}

func GenerateRandomBytes(n int) ([]byte) {
    b := make([]byte, n)
    _, err := rand.Read(b)

    if err != nil {
        return nil
    }

    return b
}

func (t *SimpleChaincode) get_volumes(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	//select range
	resultsIterator, err := stub.RangeQueryState("0", "9999999999")

	if err != nil {
		return nil, errors.New("[IP][Query] Unknown error")
	}

	field := args[0]
	value := args[1]
	fmt.Println(field)
	fmt.Println(value)
	// logisticProviderId := args[1]
	// pendingOrder, err := strconv.ParseBool(args[2])
	// findAll, err := strconv.ParseBool(args[3])

	hasResult := false

	defer resultsIterator.Close()

	result := "{\"volumes\": ["

	for resultsIterator.HasNext() {
		queryKeyAsStr, queryValAsBytes, err := resultsIterator.Next()

		fmt.Println("[IP][Query] hack: " + queryKeyAsStr)

		if err != nil {
			return nil, errors.New("[IP][Query] Unknown error")
		}

		var volume Volume
		json.Unmarshal(queryValAsBytes, &volume)
		fmt.Println(string(queryValAsBytes));

		if field == "trackerId" {
			if volume.TrackId == value {
				result += string(queryValAsBytes) + ","
				hasResult = true
			}
		} else if field == "shipper" {
			if volume.Shipper == value && volume.Status == "CRIADO" {
				result += string(queryValAsBytes) + ","
				hasResult = true
			}
		} else if field == "logistic_provider" {
			if volume.LogisticProvider == value {
				result += string(queryValAsBytes) + ","
				hasResult = true
			}
		} else {
			result += string(queryValAsBytes) + ","
			hasResult = true
		}

		// clientIdOk := clientId == "-1" || volume.ClientId == clientId
		// logisticProviderIdOk := logisticProviderId == "-1" || volume.LogisticProviderId == logisticProviderId

		// var findPendingOk bool

		// if pendingOrder {
		// 	findPendingOk = (volume.LogisticProviderFinalShippingCost == 0)
		// } else {
		// 	findPendingOk = (volume.LogisticProviderFinalShippingCost != 0)
		// }

		// fmt.Println("[IP][Query] ClientId: " + clientId + " | LogisticProviderId: " + logisticProviderId + " | PendingOrder: " + strconv.FormatBool(pendingOrder) + " | ClientIdOk: " + strconv.FormatBool(clientIdOk) + " | LogisticProviderIdOk: " + strconv.FormatBool(logisticProviderIdOk) + " | FindPendingOk: " + strconv.FormatBool(findPendingOk) + " | FindAll: " + strconv.FormatBool(findAll))
	}

	if hasResult {
		result = result[:len(result)-1] + "]}"
	} else {
		result = result + "]}"
	}

	return []byte(result), nil
}

func (t *SimpleChaincode) get_volume(stub shim.ChaincodeStubInterface, trackerId string) (Volume, error) {
	//select range
	resultsIterator, err := stub.RangeQueryState("0", "9999999999")
    var volume Volume
	if err != nil {
		return volume, errors.New("[IP][Query] Unknown error")
	}

	defer resultsIterator.Close()

	for resultsIterator.HasNext() {
		queryKeyAsStr, queryValAsBytes, err := resultsIterator.Next()

		fmt.Println("[IP][Query] hack: " + queryKeyAsStr)

		if err != nil {
			return volume, errors.New("[IP][Query] Unknown error")
		}

		json.Unmarshal(queryValAsBytes, &volume)
		fmt.Println(string(queryValAsBytes));

		return volume, nil
	}

	return volume, nil
}<|endoftext|>


<commit_before>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package backups

import (
	"bytes"
	"compress/gzip"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"

	"github.com/juju/errors"
	"github.com/juju/utils/tar"

	"github.com/juju/juju/version"
)

const (
	contentDir   = "juju-backup"
	filesBundle  = "root.tar"
	dbDumpDir    = "dump"
	metadataFile = "metadata.json"
)

var legacyVersion = version.Number{Major: 1, Minor: 20}

// ArchivePaths holds the paths to the files and directories in a
// backup archive.
type ArchivePaths struct {
	// ContentDir is the path to the directory within the archive
	// containing all the contents. It is the only file or directory at
	// the top-level of the archive and everything else in the archive
	// is contained in the content directory.
	ContentDir string

	// FilesBundle is the path to the tar file inside the archive
	// containing all the state-related files (with the exception of the
	// DB dump files) gathered in by the backup machinery.
	FilesBundle string

	// DBDumpDir is the path to the directory within the archive
	// contents that contains all the files dumped from the juju state
	// database.
	DBDumpDir string

	// MetadataFile is the path to the metadata file.
	MetadataFile string
}

// NewCanonicalArchivePaths composes a new ArchivePaths with default
// values set. These values are relative (un-rooted) and the canonical
// slash ("/") is the path separator. Thus the paths are suitable for
// resolving the paths in a backup archive file (which is a tar file).
func NewCanonicalArchivePaths() ArchivePaths {
	return ArchivePaths{
		ContentDir:   contentDir,
		FilesBundle:  path.Join(contentDir, filesBundle),
		DBDumpDir:    path.Join(contentDir, dbDumpDir),
		MetadataFile: path.Join(contentDir, metadataFile),
	}
}

// NonCanonicalArchivePaths builds a new ArchivePaths using default
// values, rooted at the provided rootDir. The path separator used is
// platform-dependent. The resulting paths are suitable for locating
// backup archive contents in a directory into which an archive has
// been unpacked.
func NewNonCanonicalArchivePaths(rootDir string) ArchivePaths {
	return ArchivePaths{
		ContentDir:   filepath.Join(rootDir, contentDir),
		FilesBundle:  filepath.Join(rootDir, contentDir, filesBundle),
		DBDumpDir:    filepath.Join(rootDir, contentDir, dbDumpDir),
		MetadataFile: filepath.Join(rootDir, contentDir, metadataFile),
	}
}

// ArchiveWorkspace is a wrapper around backup archive info that has a
// concrete root directory and an archive unpacked in it.
type ArchiveWorkspace struct {
	ArchivePaths
	RootDir string
}

func newArchiveWorkspace() (*ArchiveWorkspace, error) {
	rootdir, err := ioutil.TempDir("", "juju-backups-")
	if err != nil {
		return nil, errors.Annotate(err, "while creating workspace dir")
	}

	ws := ArchiveWorkspace{
		ArchivePaths: NewNonCanonicalArchivePaths(rootdir),
		RootDir:      rootdir,
	}
	return &ws, nil
}

// NewArchiveWorkspaceReader returns a new archive workspace with a new
// workspace dir populated from the archive file.
func NewArchiveWorkspaceReader(archiveFile io.Reader) (*ArchiveWorkspace, error) {
	ws, err := newArchiveWorkspace()
	if err != nil {
		return nil, errors.Trace(err)
	}
	err = unpackCompressedReader(ws.RootDir, archiveFile)
	return ws, errors.Trace(err)
}

func unpackCompressedReader(targetDir string, tarFile io.Reader) error {
	tarFile, err := gzip.NewReader(tarFile)
	if err != nil {
		return errors.Annotate(err, "while uncompressing archive file")
	}
	err = tar.UntarFiles(tarFile, targetDir)
	return errors.Trace(err)
}

// Close cleans up the workspace dir.
func (ws *ArchiveWorkspace) Close() error {
	err := os.RemoveAll(ws.RootDir)
	return errors.Trace(err)
}

// UnpackFilesBundle unpacks the archived files bundle into the targeted dir.
func (ws *ArchiveWorkspace) UnpackFilesBundle(targetRoot string) error {
	tarFile, err := os.Open(ws.FilesBundle)
	if err != nil {
		return errors.Trace(err)
	}
	defer tarFile.Close()

	err = tar.UntarFiles(tarFile, targetRoot)
	return errors.Trace(err)
}

// OpenBundledFile returns an open ReadCloser for the corresponding file in
// the archived files bundle.
func (ws *ArchiveWorkspace) OpenBundledFile(filename string) (io.Reader, error) {
	if filepath.IsAbs(filename) {
		return nil, errors.Errorf("filename must be relative, got %q", filename)
	}

	tarFile, err := os.Open(ws.FilesBundle)
	if err != nil {
		return nil, errors.Trace(err)
	}

	_, file, err := tar.FindFile(tarFile, filename)
	if err != nil {
		tarFile.Close()
		return nil, errors.Trace(err)
	}
	return file, nil
}

// Metadata returns the metadata derived from the JSON file in the archive.
func (ws *ArchiveWorkspace) Metadata() (*Metadata, error) {
	metaFile, err := os.Open(ws.MetadataFile)
	if err != nil {
		return nil, errors.Trace(err)
	}
	defer metaFile.Close()

	meta, err := NewMetadataJSONReader(metaFile)
	return meta, errors.Trace(err)
}

// ArchiveData is a wrapper around a the uncompressed data in a backup
// archive file. It provides access to the content of the archive.
type ArchiveData struct {
	ArchivePaths
	data []byte
}

// NewArchiveData builds a new archive data wrapper for the given
// uncompressed data.
func NewArchiveData(data []byte) *ArchiveData {
	return &ArchiveData{
		ArchivePaths: NewCanonicalArchivePaths(),
		data:         data,
	}
}

// NewArchiveReader returns a new archive data wrapper for the data in the
// provided reader.
func NewArchiveDataReader(r io.Reader) (*ArchiveData, error) {
	gzr, err := gzip.NewReader(r)
	if err != nil {
		return nil, errors.Trace(err)
	}
	defer gzr.Close()

	data, err := ioutil.ReadAll(gzr)
	if err != nil {
		return nil, errors.Trace(err)
	}

	return NewArchiveData(data), nil
}

// NewBuffer wraps the archive data in a Buffer.
func (ad *ArchiveData) NewBuffer() *bytes.Buffer {
	return bytes.NewBuffer(ad.data)
}

// Metadata returns the metadata stored in the backup archive.  If no
// metadata is there, errors.NotFound is returned.
func (ad *ArchiveData) Metadata() (*Metadata, error) {
	buf := ad.NewBuffer()
	_, metaFile, err := tar.FindFile(buf, ad.MetadataFile)
	if err != nil {
		return nil, errors.Trace(err)
	}

	meta, err := NewMetadataJSONReader(metaFile)
	return meta, errors.Trace(err)
}

// Version returns the juju version under which the backup archive
// was created.  If no version is found in the archive, it must come
// from before backup archives included the version.  In that case we
// return version 1.20.
func (ad *ArchiveData) Version() (*version.Number, error) {
	meta, err := ad.Metadata()
	if errors.IsNotFound(err) {
		return &legacyVersion, nil
	}
	if err != nil {
		return nil, errors.Trace(err)
	}

	return &meta.Origin.Version, nil
}
<commit_msg>Add some warnings about resource usage and backup archives.<commit_after>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package backups

import (
	"bytes"
	"compress/gzip"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"

	"github.com/juju/errors"
	"github.com/juju/utils/tar"

	"github.com/juju/juju/version"
)

const (
	contentDir   = "juju-backup"
	filesBundle  = "root.tar"
	dbDumpDir    = "dump"
	metadataFile = "metadata.json"
)

var legacyVersion = version.Number{Major: 1, Minor: 20}

// ArchivePaths holds the paths to the files and directories in a
// backup archive.
type ArchivePaths struct {
	// ContentDir is the path to the directory within the archive
	// containing all the contents. It is the only file or directory at
	// the top-level of the archive and everything else in the archive
	// is contained in the content directory.
	ContentDir string

	// FilesBundle is the path to the tar file inside the archive
	// containing all the state-related files (with the exception of the
	// DB dump files) gathered in by the backup machinery.
	FilesBundle string

	// DBDumpDir is the path to the directory within the archive
	// contents that contains all the files dumped from the juju state
	// database.
	DBDumpDir string

	// MetadataFile is the path to the metadata file.
	MetadataFile string
}

// NewCanonicalArchivePaths composes a new ArchivePaths with default
// values set. These values are relative (un-rooted) and the canonical
// slash ("/") is the path separator. Thus the paths are suitable for
// resolving the paths in a backup archive file (which is a tar file).
func NewCanonicalArchivePaths() ArchivePaths {
	return ArchivePaths{
		ContentDir:   contentDir,
		FilesBundle:  path.Join(contentDir, filesBundle),
		DBDumpDir:    path.Join(contentDir, dbDumpDir),
		MetadataFile: path.Join(contentDir, metadataFile),
	}
}

// NonCanonicalArchivePaths builds a new ArchivePaths using default
// values, rooted at the provided rootDir. The path separator used is
// platform-dependent. The resulting paths are suitable for locating
// backup archive contents in a directory into which an archive has
// been unpacked.
func NewNonCanonicalArchivePaths(rootDir string) ArchivePaths {
	return ArchivePaths{
		ContentDir:   filepath.Join(rootDir, contentDir),
		FilesBundle:  filepath.Join(rootDir, contentDir, filesBundle),
		DBDumpDir:    filepath.Join(rootDir, contentDir, dbDumpDir),
		MetadataFile: filepath.Join(rootDir, contentDir, metadataFile),
	}
}

// ArchiveWorkspace is a wrapper around backup archive info that has a
// concrete root directory and an archive unpacked in it.
type ArchiveWorkspace struct {
	ArchivePaths
	RootDir string
}

func newArchiveWorkspace() (*ArchiveWorkspace, error) {
	rootdir, err := ioutil.TempDir("", "juju-backups-")
	if err != nil {
		return nil, errors.Annotate(err, "while creating workspace dir")
	}

	ws := ArchiveWorkspace{
		ArchivePaths: NewNonCanonicalArchivePaths(rootdir),
		RootDir:      rootdir,
	}
	return &ws, nil
}

// NewArchiveWorkspaceReader returns a new archive workspace with a new
// workspace dir populated from the archive. Note that this involves
// unpacking the entire archive into a directory under the host's
// "temporary" directory. For relatively large archives this could have
// adverse effects on hosts with little disk space.
func NewArchiveWorkspaceReader(archive io.Reader) (*ArchiveWorkspace, error) {
	ws, err := newArchiveWorkspace()
	if err != nil {
		return nil, errors.Trace(err)
	}
	err = unpackCompressedReader(ws.RootDir, archive)
	return ws, errors.Trace(err)
}

func unpackCompressedReader(targetDir string, tarFile io.Reader) error {
	tarFile, err := gzip.NewReader(tarFile)
	if err != nil {
		return errors.Annotate(err, "while uncompressing archive file")
	}
	err = tar.UntarFiles(tarFile, targetDir)
	return errors.Trace(err)
}

// Close cleans up the workspace dir.
func (ws *ArchiveWorkspace) Close() error {
	err := os.RemoveAll(ws.RootDir)
	return errors.Trace(err)
}

// UnpackFilesBundle unpacks the archived files bundle into the targeted dir.
func (ws *ArchiveWorkspace) UnpackFilesBundle(targetRoot string) error {
	tarFile, err := os.Open(ws.FilesBundle)
	if err != nil {
		return errors.Trace(err)
	}
	defer tarFile.Close()

	err = tar.UntarFiles(tarFile, targetRoot)
	return errors.Trace(err)
}

// OpenBundledFile returns an open ReadCloser for the corresponding file in
// the archived files bundle.
func (ws *ArchiveWorkspace) OpenBundledFile(filename string) (io.Reader, error) {
	if filepath.IsAbs(filename) {
		return nil, errors.Errorf("filename must be relative, got %q", filename)
	}

	tarFile, err := os.Open(ws.FilesBundle)
	if err != nil {
		return nil, errors.Trace(err)
	}

	_, file, err := tar.FindFile(tarFile, filename)
	if err != nil {
		tarFile.Close()
		return nil, errors.Trace(err)
	}
	return file, nil
}

// Metadata returns the metadata derived from the JSON file in the archive.
func (ws *ArchiveWorkspace) Metadata() (*Metadata, error) {
	metaFile, err := os.Open(ws.MetadataFile)
	if err != nil {
		return nil, errors.Trace(err)
	}
	defer metaFile.Close()

	meta, err := NewMetadataJSONReader(metaFile)
	return meta, errors.Trace(err)
}

// ArchiveData is a wrapper around a the uncompressed data in a backup
// archive file. It provides access to the content of the archive. While
// ArchiveData provides useful functionality, it may not be appropriate
// for large archives. The contents of the archive are kept in-memory,
// so large archives could be too taxing on the host. In that case
// consider using ArchiveWorkspace instead.
type ArchiveData struct {
	ArchivePaths
	data []byte
}

// NewArchiveData builds a new archive data wrapper for the given
// uncompressed data.
func NewArchiveData(data []byte) *ArchiveData {
	return &ArchiveData{
		ArchivePaths: NewCanonicalArchivePaths(),
		data:         data,
	}
}

// NewArchiveReader returns a new archive data wrapper for the data in
// the provided reader. Note that the entire archive will be read into
// memory and kept there. So for relatively large archives it will often
// be more appropriate to use ArchiveWorkspace instead.
func NewArchiveDataReader(r io.Reader) (*ArchiveData, error) {
	gzr, err := gzip.NewReader(r)
	if err != nil {
		return nil, errors.Trace(err)
	}
	defer gzr.Close()

	data, err := ioutil.ReadAll(gzr)
	if err != nil {
		return nil, errors.Trace(err)
	}

	return NewArchiveData(data), nil
}

// NewBuffer wraps the archive data in a Buffer.
func (ad *ArchiveData) NewBuffer() *bytes.Buffer {
	return bytes.NewBuffer(ad.data)
}

// Metadata returns the metadata stored in the backup archive.  If no
// metadata is there, errors.NotFound is returned.
func (ad *ArchiveData) Metadata() (*Metadata, error) {
	buf := ad.NewBuffer()
	_, metaFile, err := tar.FindFile(buf, ad.MetadataFile)
	if err != nil {
		return nil, errors.Trace(err)
	}

	meta, err := NewMetadataJSONReader(metaFile)
	return meta, errors.Trace(err)
}

// Version returns the juju version under which the backup archive
// was created.  If no version is found in the archive, it must come
// from before backup archives included the version.  In that case we
// return version 1.20.
func (ad *ArchiveData) Version() (*version.Number, error) {
	meta, err := ad.Metadata()
	if errors.IsNotFound(err) {
		return &legacyVersion, nil
	}
	if err != nil {
		return nil, errors.Trace(err)
	}

	return &meta.Origin.Version, nil
}
<|endoftext|>


<commit_before>package v1

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"path"
	"strings"
	"time"
)

var (
	ErrNotFound        = errors.New("Not found")
	defaultHTTPTimeout = 30 * time.Second
)

type RegistryClient struct {
	URL        *url.URL
	tlsConfig  *tls.Config
	httpClient *http.Client
}

type Repo struct {
	Namespace  string
	Repository string
}

func parseRepo(repo string) Repo {
	namespace := "library"
	r := repo

	if strings.Index(repo, "/") != -1 {
		parts := strings.Split(repo, "/")
		namespace = parts[0]
		r = path.Join(parts[1:]...)
	}

	return Repo{
		Namespace:  namespace,
		Repository: r,
	}
}

func newHTTPClient(u *url.URL, tlsConfig *tls.Config, timeout time.Duration) *http.Client {
	httpTransport := &http.Transport{
		TLSClientConfig: tlsConfig,
	}

	httpTransport.Dial = func(proto, addr string) (net.Conn, error) {
		return net.DialTimeout(proto, addr, timeout)
	}
	return &http.Client{Transport: httpTransport}
}

func NewRegistryClient(registryUrl string, tlsConfig *tls.Config) (*RegistryClient, error) {
	u, err := url.Parse(registryUrl)
	if err != nil {
		return nil, err
	}
	httpClient := newHTTPClient(u, tlsConfig, defaultHTTPTimeout)
	return &RegistryClient{
		URL:        u,
		httpClient: httpClient,
		tlsConfig:  tlsConfig,
	}, nil
}

func (client *RegistryClient) doRequest(method string, path string, body []byte, headers map[string]string) ([]byte, error) {
	b := bytes.NewBuffer(body)

	req, err := http.NewRequest(method, client.URL.String()+"/v1"+path, b)
	if err != nil {
		return nil, err
	}

	req.Header.Add("Content-Type", "application/json")
	if headers != nil {
		for header, value := range headers {
			req.Header.Add(header, value)
		}
	}

	resp, err := client.httpClient.Do(req)
	if err != nil {
		if !strings.Contains(err.Error(), "connection refused") && client.tlsConfig == nil {
			return nil, fmt.Errorf("%v. Are you trying to connect to a TLS-enabled daemon without TLS?", err)
		}
		return nil, err
	}

	defer resp.Body.Close()

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 404 {
		return nil, ErrNotFound
	}

	if resp.StatusCode >= 400 {
		return nil, Error{StatusCode: resp.StatusCode, Status: resp.Status, msg: string(data)}
	}

	return data, nil
}

func (client *RegistryClient) Search(query string, page int, numResults int) (*SearchResult, error) {
	if numResults < 1 {
		numResults = 100
	}
	uri := fmt.Sprintf("/search?q=%s&n=%d&page=%d", query, numResults, page)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}

	res := &SearchResult{}
	if err := json.Unmarshal(data, &res); err != nil {
		return nil, err
	}

	// convert the simple results to rich Repository results
	repos := []*Repository{}
	for _, repo := range res.Results {
		r, err := client.Repository(repo.Name)
		if err != nil {
			return nil, err
		}

		repos = append(repos, r)
	}

	res.Results = repos

	return res, nil
}

func (client *RegistryClient) DeleteRepository(repo string) error {
	r := parseRepo(repo)
	uri := fmt.Sprintf("/repositories/%s/%s/", r.Namespace, r.Repository)
	if _, err := client.doRequest("DELETE", uri, nil, nil); err != nil {
		return err
	}

	return nil
}

func (client *RegistryClient) DeleteTag(repo string, tag string) error {
	r := parseRepo(repo)
	uri := fmt.Sprintf("/repositories/%s/%s/tags/%s", r.Namespace, r.Repository, tag)
	if _, err := client.doRequest("DELETE", uri, nil, nil); err != nil {
		return err
	}

	return nil
}

func (client *RegistryClient) Layer(id string) (*Layer, error) {
	uri := fmt.Sprintf("/images/%s/json", id)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}

	layer := &Layer{}
	if err := json.Unmarshal(data, &layer); err != nil {
		return nil, err
	}

	return layer, nil
}

func (client *RegistryClient) Repository(name string) (*Repository, error) {
	r := parseRepo(name)
	uri := fmt.Sprintf("/repositories/%s/%s/tags", r.Namespace, r.Repository)
	repoTags := map[string]string{}

	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}

	if err := json.Unmarshal(data, &repoTags); err != nil {
		return nil, err
	}

	layers := []Layer{}
	tags := []Tag{}
	size := int64(0)

	for n, id := range repoTags {
		uri := fmt.Sprintf("/images/%s/json", id)
		layer := &Layer{}

		data, err := client.doRequest("GET", uri, nil, nil)
		if err != nil {
			return nil, err
		}

		if err := json.Unmarshal(data, &layer); err != nil {
			return nil, err
		}

		uri = fmt.Sprintf("/images/%s/ancestry", id)

		ancestry := []string{}

		data, err = client.doRequest("GET", uri, nil, nil)
		if err != nil {
			return nil, err
		}

		if err = json.Unmarshal(data, &ancestry); err != nil {
			return nil, err
		}

		tag := &Tag{
			ID:   id,
			Name: n,
		}

		tags = append(tags, *tag)
		layer.Ancestry = ancestry

		layers = append(layers, *layer)

		// parse ancestor layers
		for _, i := range ancestry {
			uri = fmt.Sprintf("/images/%s/json", i)
			l := &Layer{}

			data, err = client.doRequest("GET", uri, nil, nil)
			if err != nil {
				return nil, err
			}

			if err = json.Unmarshal(data, &l); err != nil {
				return nil, err
			}
			size += l.Size
			layers = append(layers, *l)
		}
	}

	return &Repository{
		Name:       path.Join(r.Namespace, r.Repository),
		Namespace:  r.Namespace,
		Repository: r.Repository,
		Tags:       tags,
		Layers:     layers,
		Size:       size,
	}, nil
}
<commit_msg>fix reverted commit for repo sizes<commit_after>package v1

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"path"
	"strings"
	"time"
)

var (
	ErrNotFound        = errors.New("Not found")
	defaultHTTPTimeout = 30 * time.Second
)

type RegistryClient struct {
	URL        *url.URL
	tlsConfig  *tls.Config
	httpClient *http.Client
}

type Repo struct {
	Namespace  string
	Repository string
}

func parseRepo(repo string) Repo {
	namespace := "library"
	r := repo

	if strings.Index(repo, "/") != -1 {
		parts := strings.Split(repo, "/")
		namespace = parts[0]
		r = path.Join(parts[1:]...)
	}

	return Repo{
		Namespace:  namespace,
		Repository: r,
	}
}

func newHTTPClient(u *url.URL, tlsConfig *tls.Config, timeout time.Duration) *http.Client {
	httpTransport := &http.Transport{
		TLSClientConfig: tlsConfig,
	}

	httpTransport.Dial = func(proto, addr string) (net.Conn, error) {
		return net.DialTimeout(proto, addr, timeout)
	}
	return &http.Client{Transport: httpTransport}
}

func NewRegistryClient(registryUrl string, tlsConfig *tls.Config) (*RegistryClient, error) {
	u, err := url.Parse(registryUrl)
	if err != nil {
		return nil, err
	}
	httpClient := newHTTPClient(u, tlsConfig, defaultHTTPTimeout)
	return &RegistryClient{
		URL:        u,
		httpClient: httpClient,
		tlsConfig:  tlsConfig,
	}, nil
}

func (client *RegistryClient) doRequest(method string, path string, body []byte, headers map[string]string) ([]byte, error) {
	b := bytes.NewBuffer(body)

	req, err := http.NewRequest(method, client.URL.String()+"/v1"+path, b)
	if err != nil {
		return nil, err
	}

	req.Header.Add("Content-Type", "application/json")
	if headers != nil {
		for header, value := range headers {
			req.Header.Add(header, value)
		}
	}

	resp, err := client.httpClient.Do(req)
	if err != nil {
		if !strings.Contains(err.Error(), "connection refused") && client.tlsConfig == nil {
			return nil, fmt.Errorf("%v. Are you trying to connect to a TLS-enabled daemon without TLS?", err)
		}
		return nil, err
	}

	defer resp.Body.Close()

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 404 {
		return nil, ErrNotFound
	}

	if resp.StatusCode >= 400 {
		return nil, Error{StatusCode: resp.StatusCode, Status: resp.Status, msg: string(data)}
	}

	return data, nil
}

func (client *RegistryClient) Search(query string, page int, numResults int) (*SearchResult, error) {
	if numResults < 1 {
		numResults = 100
	}
	uri := fmt.Sprintf("/search?q=%s&n=%d&page=%d", query, numResults, page)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}

	res := &SearchResult{}
	if err := json.Unmarshal(data, &res); err != nil {
		return nil, err
	}

	// convert the simple results to rich Repository results
	repos := []*Repository{}
	for _, repo := range res.Results {
		r, err := client.Repository(repo.Name)
		if err != nil {
			return nil, err
		}

		repos = append(repos, r)
	}

	res.Results = repos

	return res, nil
}

func (client *RegistryClient) DeleteRepository(repo string) error {
	r := parseRepo(repo)
	uri := fmt.Sprintf("/repositories/%s/%s/", r.Namespace, r.Repository)
	if _, err := client.doRequest("DELETE", uri, nil, nil); err != nil {
		return err
	}

	return nil
}

func (client *RegistryClient) DeleteTag(repo string, tag string) error {
	r := parseRepo(repo)
	uri := fmt.Sprintf("/repositories/%s/%s/tags/%s", r.Namespace, r.Repository, tag)
	if _, err := client.doRequest("DELETE", uri, nil, nil); err != nil {
		return err
	}

	return nil
}

func (client *RegistryClient) Layer(id string) (*Layer, error) {
	uri := fmt.Sprintf("/images/%s/json", id)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}

	layer := &Layer{}
	if err := json.Unmarshal(data, &layer); err != nil {
		return nil, err
	}

	return layer, nil
}

func (client *RegistryClient) Repository(name string) (*Repository, error) {
	r := parseRepo(name)
	uri := fmt.Sprintf("/repositories/%s/%s/tags", r.Namespace, r.Repository)
	repoTags := map[string]string{}

	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}

	if err := json.Unmarshal(data, &repoTags); err != nil {
		return nil, err
	}

	layers := []Layer{}
	tags := []Tag{}
	size := int64(0)

	for n, id := range repoTags {
		uri := fmt.Sprintf("/images/%s/json", id)
		layer := &Layer{}

		data, err := client.doRequest("GET", uri, nil, nil)
		if err != nil {
			return nil, err
		}

		if err := json.Unmarshal(data, &layer); err != nil {
			return nil, err
		}

		uri = fmt.Sprintf("/images/%s/ancestry", id)

		ancestry := []string{}

		data, err = client.doRequest("GET", uri, nil, nil)
		if err != nil {
			return nil, err
		}

		if err = json.Unmarshal(data, &ancestry); err != nil {
			return nil, err
		}

		tag := &Tag{
			ID:   id,
			Name: n,
		}

		tags = append(tags, *tag)
		layer.Ancestry = ancestry

		layers = append(layers, *layer)

		// parse ancestor layers
		for _, i := range ancestry {
			uri = fmt.Sprintf("/images/%s/json", i)
			l := &Layer{}

			data, err = client.doRequest("GET", uri, nil, nil)
			if err != nil {
				return nil, err
			}

			if err = json.Unmarshal(data, &l); err != nil {
				return nil, err
			}
			size += l.Size
			layers = append(layers, *l)
		}
	}

	return &Repository{
		Name:       path.Join(r.Namespace, r.Repository),
		Namespace:  r.Namespace,
		Repository: r.Repository,
		Tags:       tags,
		Layers:     layers,
		Size:       int64(size) / int64(len(tags)),
	}, nil
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"

	"github.com/arthurkiller/perfm"
)

type job struct {
	// job data here
	url string
}

// Copy will called in parallel
func (j *job) Copy() *job {
	jc := *j
	return &jc
}

func (j *job) Pre() error {
	// do pre job
	return nil
}
func (j *job) Do() error {
	// do benchmark job
	_, err := http.Get(j.url)
	return err
}
func (j *job) After() error {
	// do clean job
	return nil
}

func main() {
	perfm := perfm.New(perfm.WithBinsNumber(15), perfm.WithParallel(1), perfm.WithNumber(20))

	j := &job{}
	j.url = "http://www.baidu.com"

	perfm.Regist(j)

	perfm.Start()
	perfm.Wait()
}
<commit_msg>fix demo code<commit_after>package main

import (
	"net/http"

	"github.com/arthurkiller/perfm"
)

type job struct {
	// job data here
	url string
}

// Copy will called in parallel
func (j *job) Copy() perfm.Job {
	jc := *j
	return &jc
}

func (j *job) Pre() {
	// do pre job
}
func (j *job) Do() error {
	// do benchmark job
	_, err := http.Get(j.url)
	return err
}
func (j *job) After() {
	// do clean job
}

func main() {
	perfm := perfm.New(perfm.WithBinsNumber(15), perfm.WithParallel(1), perfm.WithNumber(20))

	j := &job{}
	j.url = "http://www.baidu.com"

	perfm.Regist(j)

	perfm.Start()
	perfm.Wait()
}
<|endoftext|>


<commit_before>package registry

import (
	"os"

	"github.com/nildev/lib/Godeps/_workspace/src/gopkg.in/mgo.v2"
)

var (
	mongoDBClientURL = "mongodb://localhost:27017/test"
	databaseName     = "default"
)

// These constants is public API, being taken by lib from environment
const (
	NDMongoDBURL   = "ND_MONGODB_URL"
	NDDatabaseName = "ND_DATABASE_NAME"
	NDEnv          = "ND_ENV"

	EnvDev = "dev"
)

// GetEnv return environment
func GetEnv() string {
	env := os.Getenv(NDEnv)
	if env == "" {
		env = EnvDev
	}

	return env
}

// GetMongoDBClient create mongoDB client based on client
func GetMongoDBClient() (*mgo.Session, error) {
	envValue := os.Getenv(NDMongoDBURL)
	if envValue != "" {
		mongoDBClientURL = envValue
	}

	session, err := mgo.Dial(mongoDBClientURL)
	//	session.SetSafe(&mgo.Safe{})
	return session, err
}

// GetDatabaseName returns DB name
func GetDatabaseName() string {
	envValue := os.Getenv(NDDatabaseName)
	if envValue != "" {
		databaseName = envValue
	}
	return databaseName
}
<commit_msg>Add factory for iron.io queue<commit_after>package registry

import (
	"os"

	"github.com/iron-io/iron_go3/mq"
	"github.com/nildev/lib/Godeps/_workspace/src/gopkg.in/mgo.v2"
)

var (
	mongoDBClientURL = "mongodb://localhost:27017/test"
	databaseName     = "default"
)

// These constants is public API, being taken by lib from environment
const (
	NDMongoDBURL   = "ND_MONGODB_URL"
	NDDatabaseName = "ND_DATABASE_NAME"
	NDEnv          = "ND_ENV"

	EnvDev = "dev"
)

// GetEnv return environment
func GetEnv() string {
	env := os.Getenv(NDEnv)
	if env == "" {
		env = EnvDev
	}

	return env
}

// CreateMongoDBClient create MongoDB client
func CreateMongoDBClient() (*mgo.Session, error) {
	envValue := os.Getenv(NDMongoDBURL)
	if envValue != "" {
		mongoDBClientURL = envValue
	}

	session, err := mgo.Dial(mongoDBClientURL)
	//	session.SetSafe(&mgo.Safe{})
	return session, err
}

// GetDatabaseName returns DB name
func GetDatabaseName() string {
	envValue := os.Getenv(NDDatabaseName)
	if envValue != "" {
		databaseName = envValue
	}
	return databaseName
}

// CreateIronQueue creates and returns Iron.io queue
func CreateIronQueue(name string) (*mq.Queue, error) {
	subscribers := []mq.QueueSubscriber{}
	subscription := mq.PushInfo{
		Retries:      3,
		RetriesDelay: 60,
		ErrorQueue:   "error_queue",
		Subscribers:  subscribers,
	}
	queue_type := "push"
	queueInfo := mq.QueueInfo{Type: queue_type, MessageExpiration: 60, MessageTimeout: 56, Push: &subscription}
	_, err := mq.CreateQueue(name, queueInfo)
	if err != nil {
		return nil, err
	}

	queue := mq.New(name)
	return &queue, nil
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"net/url"
	"os"
	"path/filepath"
	"reflect"
	"testing"

	. "github.com/onsi/gomega"
)

func TestLocalRepositoryFromFullPath(t *testing.T) {
	origLocalRepositryRoots := _localRepositoryRoots
	_localRepositoryRoots = []string{"/repos"}
	defer func() { _localRepositoryRoots = origLocalRepositryRoots }()

	testCases := []struct {
		fpath    string
		expect   string
		subpaths []string
	}{{
		fpath:    "/repos/github.com/motemen/ghq",
		expect:   "motemen/ghq",
		subpaths: []string{"ghq", "motemen/ghq", "github.com/motemen/ghq"},
	}, {
		fpath:    "/repos/stash.com/scm/motemen/ghq",
		expect:   "scm/motemen/ghq",
		subpaths: []string{"ghq", "motemen/ghq", "scm/motemen/ghq", "stash.com/scm/motemen/ghq"},
	}}

	for _, tc := range testCases {
		t.Run(tc.fpath, func(t *testing.T) {
			r, err := LocalRepositoryFromFullPath(tc.fpath, nil)
			if err != nil {
				t.Errorf("error should be nil but: %s", err)
			}
			if r.NonHostPath() != tc.expect {
				t.Errorf("NonHostPath: got: %s, expect: %s", r.NonHostPath(), tc.expect)
			}
			if !reflect.DeepEqual(r.Subpaths(), tc.subpaths) {
				t.Errorf("Subpaths:\ngot:    %+v\nexpect: %+v", r.Subpaths(), tc.subpaths)
			}
		})
	}
}

func TestNewLocalRepository(t *testing.T) {
	RegisterTestingT(t)
	_localRepositoryRoots = []string{"/repos"}

	githubURL, _ := url.Parse("ssh://git@github.com/motemen/ghq.git")
	r, err := LocalRepositoryFromURL(githubURL)
	Expect(err).To(BeNil())
	Expect(r.FullPath).To(Equal("/repos/github.com/motemen/ghq"))

	stashURL, _ := url.Parse("ssh://git@stash.com/scm/motemen/ghq")
	r, _ = LocalRepositoryFromURL(stashURL)
	Expect(r.FullPath).To(Equal("/repos/stash.com/scm/motemen/ghq"))

	svnSourceforgeURL, _ := url.Parse("http://svn.code.sf.net/p/ghq/code/trunk")
	r, _ = LocalRepositoryFromURL(svnSourceforgeURL)
	Expect(r.FullPath).To(Equal("/repos/svn.code.sf.net/p/ghq/code/trunk"))

	gitSourceforgeURL, _ := url.Parse("http://git.code.sf.net/p/ghq/code")
	r, _ = LocalRepositoryFromURL(gitSourceforgeURL)
	Expect(r.FullPath).To(Equal("/repos/git.code.sf.net/p/ghq/code"))

	svnSourceforgeJpURL, _ := url.Parse("http://scm.sourceforge.jp/svnroot/ghq/")
	r, _ = LocalRepositoryFromURL(svnSourceforgeJpURL)
	Expect(r.FullPath).To(Equal("/repos/scm.sourceforge.jp/svnroot/ghq"))

	gitSourceforgeJpURL, _ := url.Parse("http://scm.sourceforge.jp/gitroot/ghq/ghq.git")
	r, _ = LocalRepositoryFromURL(gitSourceforgeJpURL)
	Expect(r.FullPath).To(Equal("/repos/scm.sourceforge.jp/gitroot/ghq/ghq"))

	svnAssemblaURL, _ := url.Parse("https://subversion.assembla.com/svn/ghq/")
	r, _ = LocalRepositoryFromURL(svnAssemblaURL)
	Expect(r.FullPath).To(Equal("/repos/subversion.assembla.com/svn/ghq"))

	gitAssemblaURL, _ := url.Parse("https://git.assembla.com/ghq.git")
	r, _ = LocalRepositoryFromURL(gitAssemblaURL)
	Expect(r.FullPath).To(Equal("/repos/git.assembla.com/ghq"))
}

func TestLocalRepositoryRoots(t *testing.T) {
	RegisterTestingT(t)

	defer func(orig string) { os.Setenv("GHQ_ROOT", orig) }(os.Getenv("GHQ_ROOT"))

	_localRepositoryRoots = nil
	os.Setenv("GHQ_ROOT", "/path/to/ghqroot")
	Expect(localRepositoryRoots()).To(Equal([]string{"/path/to/ghqroot"}))

	_localRepositoryRoots = nil
	os.Setenv("GHQ_ROOT", "/path/to/ghqroot1"+string(os.PathListSeparator)+"/path/to/ghqroot2")
	Expect(localRepositoryRoots()).To(Equal([]string{"/path/to/ghqroot1", "/path/to/ghqroot2"}))
}

// https://gist.github.com/kyanny/c231f48e5d08b98ff2c3
func TestList_Symlink(t *testing.T) {
	RegisterTestingT(t)

	root, err := ioutil.TempDir("", "")
	Expect(err).To(BeNil())
	defer os.RemoveAll(root)

	symDir, err := ioutil.TempDir("", "")
	Expect(err).To(BeNil())
	defer os.RemoveAll(symDir)

	_localRepositoryRoots = []string{root}

	err = os.MkdirAll(filepath.Join(root, "github.com", "atom", "atom", ".git"), 0777)
	Expect(err).To(BeNil())

	err = os.MkdirAll(filepath.Join(root, "github.com", "zabbix", "zabbix", ".git"), 0777)
	Expect(err).To(BeNil())

	err = os.Symlink(symDir, filepath.Join(root, "github.com", "ghq"))
	Expect(err).To(BeNil())

	paths := []string{}
	walkLocalRepositories(func(repo *LocalRepository) {
		paths = append(paths, repo.RelPath)
	})

	Expect(paths).To(HaveLen(2))
}
<commit_msg>rewrite TestNewLocalRepository in table driven testing<commit_after>package main

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"testing"

	. "github.com/onsi/gomega"
)

func TestLocalRepositoryFromFullPath(t *testing.T) {
	origLocalRepositryRoots := _localRepositoryRoots
	_localRepositoryRoots = []string{"/repos"}
	defer func() { _localRepositoryRoots = origLocalRepositryRoots }()

	testCases := []struct {
		fpath    string
		expect   string
		subpaths []string
	}{{
		fpath:    "/repos/github.com/motemen/ghq",
		expect:   "motemen/ghq",
		subpaths: []string{"ghq", "motemen/ghq", "github.com/motemen/ghq"},
	}, {
		fpath:    "/repos/stash.com/scm/motemen/ghq",
		expect:   "scm/motemen/ghq",
		subpaths: []string{"ghq", "motemen/ghq", "scm/motemen/ghq", "stash.com/scm/motemen/ghq"},
	}}

	for _, tc := range testCases {
		t.Run(tc.fpath, func(t *testing.T) {
			r, err := LocalRepositoryFromFullPath(tc.fpath, nil)
			if err != nil {
				t.Errorf("error should be nil but: %s", err)
			}
			if r.NonHostPath() != tc.expect {
				t.Errorf("NonHostPath: got: %s, expect: %s", r.NonHostPath(), tc.expect)
			}
			if !reflect.DeepEqual(r.Subpaths(), tc.subpaths) {
				t.Errorf("Subpaths:\ngot:    %+v\nexpect: %+v", r.Subpaths(), tc.subpaths)
			}
		})
	}
}

func TestNewLocalRepository(t *testing.T) {
	origLocalRepositryRoots := _localRepositoryRoots
	_localRepositoryRoots = []string{"/repos"}
	defer func() { _localRepositoryRoots = origLocalRepositryRoots }()

	testCases := []struct {
		name, url, expect string
	}{{
		name:   "GitHub",
		url:    "ssh://git@github.com/motemen/ghq.git",
		expect: "/repos/github.com/motemen/ghq",
	}, {
		name:   "stash",
		url:    "ssh://git@stash.com/scm/motemen/ghq.git",
		expect: "/repos/stash.com/scm/motemen/ghq",
	}, {
		name:   "svn Sourceforge",
		url:    "http://svn.code.sf.net/p/ghq/code/trunk",
		expect: "/repos/svn.code.sf.net/p/ghq/code/trunk",
	}, {
		name:   "git Sourceforge",
		url:    "http://git.code.sf.net/p/ghq/code",
		expect: "/repos/git.code.sf.net/p/ghq/code",
	}, {
		name:   "svn Sourceforge JP",
		url:    "http://scm.sourceforge.jp/svnroot/ghq/",
		expect: "/repos/scm.sourceforge.jp/svnroot/ghq",
	}, {
		name:   "git Sourceforge JP",
		url:    "http://scm.sourceforge.jp/gitroot/ghq/ghq.git",
		expect: "/repos/scm.sourceforge.jp/gitroot/ghq/ghq",
	}, {
		name:   "svn Assembla",
		url:    "https://subversion.assembla.com/svn/ghq/",
		expect: "/repos/subversion.assembla.com/svn/ghq",
	}, {
		name:   "git Assembla",
		url:    "https://git.assembla.com/ghq.git",
		expect: "/repos/git.assembla.com/ghq",
	}}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			r, err := LocalRepositoryFromURL(mustParseURL(tc.url))
			if err != nil {
				t.Errorf("error should be nil but: %s", err)
			}
			if r.FullPath != tc.expect {
				t.Errorf("got: %s, expect: %s", r.FullPath, tc.expect)
			}
		})
	}
}

func TestLocalRepositoryRoots(t *testing.T) {
	RegisterTestingT(t)

	defer func(orig string) { os.Setenv("GHQ_ROOT", orig) }(os.Getenv("GHQ_ROOT"))

	_localRepositoryRoots = nil
	os.Setenv("GHQ_ROOT", "/path/to/ghqroot")
	Expect(localRepositoryRoots()).To(Equal([]string{"/path/to/ghqroot"}))

	_localRepositoryRoots = nil
	os.Setenv("GHQ_ROOT", "/path/to/ghqroot1"+string(os.PathListSeparator)+"/path/to/ghqroot2")
	Expect(localRepositoryRoots()).To(Equal([]string{"/path/to/ghqroot1", "/path/to/ghqroot2"}))
}

// https://gist.github.com/kyanny/c231f48e5d08b98ff2c3
func TestList_Symlink(t *testing.T) {
	RegisterTestingT(t)

	root, err := ioutil.TempDir("", "")
	Expect(err).To(BeNil())
	defer os.RemoveAll(root)

	symDir, err := ioutil.TempDir("", "")
	Expect(err).To(BeNil())
	defer os.RemoveAll(symDir)

	_localRepositoryRoots = []string{root}

	err = os.MkdirAll(filepath.Join(root, "github.com", "atom", "atom", ".git"), 0777)
	Expect(err).To(BeNil())

	err = os.MkdirAll(filepath.Join(root, "github.com", "zabbix", "zabbix", ".git"), 0777)
	Expect(err).To(BeNil())

	err = os.Symlink(symDir, filepath.Join(root, "github.com", "ghq"))
	Expect(err).To(BeNil())

	paths := []string{}
	walkLocalRepositories(func(repo *LocalRepository) {
		paths = append(paths, repo.RelPath)
	})

	Expect(paths).To(HaveLen(2))
}
<|endoftext|>


<commit_before>package xorm_test

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	_ "github.com/mattn/go-sqlite3"
	"os"
	"testing"
	"time"
	"xorm"
)

/*
CREATE TABLE `userinfo` (
	`uid` INT(10) NULL AUTO_INCREMENT,
	`username` VARCHAR(64) NULL,
	`departname` VARCHAR(64) NULL,
	`created` DATE NULL,
	PRIMARY KEY (`uid`)
);
CREATE TABLE `userdeatail` (
	`uid` INT(10) NULL,
	`intro` TEXT NULL,
	`profile` TEXT NULL,
	PRIMARY KEY (`uid`)
);
*/

type Userinfo struct {
	Uid        int64 `xorm:"id pk not null autoincr"`
	Username   string
	Departname string
	Alias      string `xorm:"-"`
	Created    time.Time
	Detail     Userdetail `xorm:"detail_id int(11)"`
	Height     float64
	Avatar     []byte
	IsMan      bool
}

type Userdetail struct {
	Id      int64
	Intro   string `xorm:"text"`
	Profile string `xorm:"varchar(2000)"`
}

var engine xorm.Engine

func directCreateTable(t *testing.T) {
	err := engine.CreateTables(&Userinfo{})
	if err != nil {
		t.Error(err)
	}
}

func mapper(t *testing.T) {
	err := engine.UnMap(&Userinfo{})
	if err != nil {
		t.Error(err)
	}

	err = engine.Map(&Userinfo{}, &Userdetail{})
	if err != nil {
		t.Error(err)
	}

	err = engine.DropAll()
	if err != nil {
		t.Error(err)
	}

	err = engine.CreateAll()
	if err != nil {
		t.Error(err)
	}
}

func insert(t *testing.T) {
	user := Userinfo{1, "xiaolunwen", "dev", "lunny", time.Now(),
		Userdetail{Id: 1}, 1.78, []byte{1, 2, 3}, true}
	_, err := engine.Insert(&user)
	if err != nil {
		t.Error(err)
	}
}

func query(t *testing.T) {
	sql := "select * from userinfo"
	results, err := engine.Query(sql)
	if err != nil {
		t.Error(err)
	}
	fmt.Println(results)
}

func exec(t *testing.T) {
	sql := "update userinfo set username=? where id=?"
	res, err := engine.Exec(sql, "xiaolun", 1)
	if err != nil {
		t.Error(err)
	}
	fmt.Println(res)
}

func insertAutoIncr(t *testing.T) {
	// auto increment insert
	user := Userinfo{Username: "xiaolunwen", Departname: "dev", Alias: "lunny", Created: time.Now(),
		Detail: Userdetail{Id: 1}, Height: 1.78, Avatar: []byte{1, 2, 3}, IsMan: true}
	_, err := engine.Insert(&user)
	if err != nil {
		t.Error(err)
	}
}

func insertMulti(t *testing.T) {
	engine.InsertMany = true
	users := []Userinfo{
		{Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
		{Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
		{Username: "xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
		{Username: "xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
	}
	_, err := engine.Insert(&users)
	if err != nil {
		t.Error(err)
	}

	engine.InsertMany = false

	users = []Userinfo{
		{Username: "xlw9", Departname: "dev", Alias: "lunny9", Created: time.Now()},
		{Username: "xlw10", Departname: "dev", Alias: "lunny10", Created: time.Now()},
		{Username: "xlw99", Departname: "dev", Alias: "lunny2", Created: time.Now()},
		{Username: "xlw1010", Departname: "dev", Alias: "lunny3", Created: time.Now()},
	}
	_, err = engine.Insert(&users)
	if err != nil {
		t.Error(err)
	}

	engine.InsertMany = true
}

func insertTwoTable(t *testing.T) {
	userdetail := Userdetail{Id: 1, Intro: "I'm a very beautiful women.", Profile: "sfsaf"}
	userinfo := Userinfo{Username: "xlw3", Departname: "dev", Alias: "lunny4", Created: time.Now(), Detail: userdetail}

	_, err := engine.Insert(&userinfo, &userdetail)
	if err != nil {
		t.Error(err)
	}
}

func update(t *testing.T) {
	// update by id
	user := Userinfo{Username: "xxx"}
	_, err := engine.Id(1).Update(&user)
	if err != nil {
		t.Error(err)
		return
	}

	_, err = engine.Update(&Userinfo{Username: "yyy"}, &user)
	if err != nil {
		t.Error(err)
	}
}

func delete(t *testing.T) {
	user := Userinfo{Uid: 1}
	_, err := engine.Delete(&user)
	if err != nil {
		t.Error(err)
	}
}

func get(t *testing.T) {
	user := Userinfo{Uid: 2}

	err := engine.Get(&user)
	if err != nil {
		t.Error(err)
	}
	fmt.Println(user)
}

func cascadeGet(t *testing.T) {
	user := Userinfo{Uid: 11}

	err := engine.Get(&user)
	if err != nil {
		t.Error(err)
	}
	fmt.Println(user)
}

func find(t *testing.T) {
	users := make([]Userinfo, 0)

	err := engine.Find(&users)
	if err != nil {
		t.Error(err)
	}
	fmt.Println(users)
}

func findMap(t *testing.T) {
	users := make(map[int64]Userinfo)

	err := engine.Find(&users)
	if err != nil {
		t.Error(err)
	}
	fmt.Println(users)
}

func count(t *testing.T) {
	user := Userinfo{Departname: "dev"}
	total, err := engine.Count(&user)
	if err != nil {
		t.Error(err)
	}
	fmt.Printf("Total %d records!!!", total)
}

func where(t *testing.T) {
	users := make([]Userinfo, 0)
	err := engine.Where("id > ?", 2).Find(&users)
	if err != nil {
		t.Error(err)
	}
	fmt.Println(users)
}

func in(t *testing.T) {
	users := make([]Userinfo, 0)
	err := engine.In("id", 1, 2, 3).Find(&users)
	if err != nil {
		t.Error(err)
		return
	}
	fmt.Println(users)

	ids := []interface{}{1, 2, 3}
	err = engine.Where("id > ?", 2).In("id", ids...).Find(&users)
	if err != nil {
		t.Error(err)
		return
	}
	fmt.Println(users)
}

func limit(t *testing.T) {
	users := make([]Userinfo, 0)
	err := engine.Limit(2, 1).Find(&users)
	if err != nil {
		t.Error(err)
	}
	fmt.Println(users)
}

func order(t *testing.T) {
	users := make([]Userinfo, 0)
	err := engine.OrderBy("id desc").Find(&users)
	if err != nil {
		t.Error(err)
	}
	fmt.Println(users)
}

func join(t *testing.T) {
	users := make([]Userinfo, 0)
	err := engine.Join("LEFT", "userdetail", "userinfo.id=userdetail.id").Find(&users)
	if err != nil {
		t.Error(err)
	}
}

func having(t *testing.T) {
	users := make([]Userinfo, 0)
	err := engine.GroupBy("username").Having("username='xlw'").Find(&users)
	if err != nil {
		t.Error(err)
	}
	fmt.Println(users)
}

func transaction(t *testing.T) {
	counter := func() {
		total, err := engine.Count(&Userinfo{})
		if err != nil {
			t.Error(err)
		}
		fmt.Printf("----now total %v records\n", total)
	}

	counter()
	defer counter()
	session, err := engine.MakeSession()
	defer session.Close()
	if err != nil {
		t.Error(err)
		return
	}

	session.Begin()
	//session.IsAutoRollback = false
	user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
	_, err = session.Insert(&user1)
	if err != nil {
		session.Rollback()
		t.Error(err)
		return
	}
	user2 := Userinfo{Username: "yyy"}
	_, err = session.Where("uid = ?", 0).Update(&user2)
	if err != nil {
		session.Rollback()
		fmt.Println(err)
		//t.Error(err)
		return
	}

	_, err = session.Delete(&user2)
	if err != nil {
		session.Rollback()
		t.Error(err)
		return
	}

	err = session.Commit()
	if err != nil {
		t.Error(err)
		return
	}
}

func combineTransaction(t *testing.T) {
	counter := func() {
		total, err := engine.Count(&Userinfo{})
		if err != nil {
			t.Error(err)
		}
		fmt.Printf("----now total %v records\n", total)
	}

	counter()
	defer counter()
	session, err := engine.MakeSession()
	defer session.Close()
	if err != nil {
		t.Error(err)
		return
	}

	session.Begin()
	//session.IsAutoRollback = false
	user1 := Userinfo{Username: "xiaoxiao2", Departname: "dev", Alias: "lunny", Created: time.Now()}
	_, err = session.Insert(&user1)
	if err != nil {
		session.Rollback()
		t.Error(err)
		return
	}
	user2 := Userinfo{Username: "zzz"}
	_, err = session.Where("id = ?", 0).Update(&user2)
	if err != nil {
		session.Rollback()
		t.Error(err)
		return
	}

	_, err = session.Exec("delete from userinfo where username = ?", user2.Username)
	if err != nil {
		session.Rollback()
		t.Error(err)
		return
	}

	err = session.Commit()
	if err != nil {
		t.Error(err)
		return
	}
}

func table(t *testing.T) {
	engine.Table("user_user").CreateTables(&Userinfo{})
}

func createMultiTables(t *testing.T) {
	session, err := engine.MakeSession()
	defer session.Close()
	if err != nil {
		t.Error(err)
		return
	}

	user := &Userinfo{}
	session.Begin()
	for i := 0; i < 10; i++ {
		err = session.Table(fmt.Sprintf("user_%v", i)).CreateTable(user)
		if err != nil {
			session.Rollback()
			t.Error(err)
			return
		}
	}
	err = session.Commit()
	if err != nil {
		t.Error(err)
	}
}

func tableOp(t *testing.T) {
	user := Userinfo{Username: "tablexiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
	tableName := fmt.Sprintf("user_%v", len(user.Username))
	id, err := engine.Table(tableName).Insert(&user)
	if err != nil {
		t.Error(err)
	}

	err = engine.Table(tableName).Get(&Userinfo{Username: "tablexiao"})
	if err != nil {
		t.Error(err)
	}

	users := make([]Userinfo, 0)
	err = engine.Table(tableName).Find(&users)
	if err != nil {
		t.Error(err)
	}

	_, err = engine.Table(tableName).Id(id).Update(&Userinfo{Username: "tableda"})
	if err != nil {
		t.Error(err)
	}

	_, err = engine.Table(tableName).Id(id).Delete(&Userinfo{})
	if err != nil {
		t.Error(err)
	}
}

func TestMysql(t *testing.T) {
	// You should drop all tables before executing this testing
	engine = xorm.Create("mysql", "root:123@/test?charset=utf8")
	engine.ShowSQL = true

	directCreateTable(t)
	mapper(t)
	insert(t)
	query(t)
	exec(t)
	insertAutoIncr(t)
	insertMulti(t)
	insertTwoTable(t)
	update(t)
	delete(t)
	get(t)
	cascadeGet(t)
	find(t)
	findMap(t)
	count(t)
	where(t)
	in(t)
	limit(t)
	order(t)
	join(t)
	having(t)
	transaction(t)
	combineTransaction(t)
	table(t)
	createMultiTables(t)
	tableOp(t)
}

func TestSqlite(t *testing.T) {
	os.Remove("./test.db")
	engine = xorm.Create("sqlite3", "./test.db")
	engine.ShowSQL = true

	directCreateTable(t)
	mapper(t)
	insert(t)
	query(t)
	exec(t)
	insertAutoIncr(t)
	insertMulti(t)
	insertTwoTable(t)
	update(t)
	delete(t)
	get(t)
	cascadeGet(t)
	find(t)
	findMap(t)
	count(t)
	where(t)
	in(t)
	limit(t)
	order(t)
	join(t)
	having(t)
	transaction(t)
	combineTransaction(t)
	table(t)
	createMultiTables(t)
	tableOp(t)
}
<commit_msg>improved tests<commit_after><|endoftext|>