<commit_before>package epos

import (
	"errors"
	"fmt"
	"github.com/feyeleanor/atomiser"
	"github.com/feyeleanor/chain"
	"strconv"
	"strings"
)

func Expression(s string) (Condition, error) {
	expr := atomiser.NewAtomiser(strings.NewReader(s)).ReadList()

	if expr == nil {
		return nil, fmt.Errorf("parsing '%s' failed", s)
	}

	return parseExpressionToCondition(expr)
}

func parseExpressionToCondition(expr *chain.Cell) (Condition, error) {
	sym, ok := expr.Head.(atomiser.Symbol)
	if !ok {
		return nil, fmt.Errorf("expected symbol, got '%v' instead", expr.Head)
	}

	sym = atomiser.Symbol(strings.ToLower(string(sym)))

	switch sym {
	case "and":
		return parseAnd(expr.Tail)
	case "or":
		return parseOr(expr.Tail)
	case "eq":
		return parseEqual(expr.Tail)
	case "id":
		return parseId(expr.Tail)
	}
	return nil, fmt.Errorf("unknown symbol '%s'", sym)
}

func parseAnd(expr *chain.Cell) (Condition, error) {
	cond := &And{}

	cur := expr
	for cur != nil {
		if subexpr, ok := cur.Head.(*chain.Cell); ok {
			if subcond, err := parseExpressionToCondition(subexpr); err != nil {
				return nil, err
			} else {
				*cond = append(*cond, subcond)
			}
		}
		cur = cur.Tail
	}

	if len(*cond) == 0 {
		return nil, errors.New("empty and expression")
	}

	return cond, nil
}

func parseOr(expr *chain.Cell) (Condition, error) {
	cond := &Or{}

	cur := expr
	for cur != nil {
		if subexpr, ok := cur.Head.(*chain.Cell); ok {
			if subcond, err := parseExpressionToCondition(subexpr); err != nil {
				return nil, err
			} else {
				*cond = append(*cond, subcond)
			}
		}
		cur = cur.Tail
	}

	if len(*cond) == 0 {
		return nil, errors.New("empty or expression")
	}

	return cond, nil
}

func parseEqual(expr *chain.Cell) (Condition, error) {
	cond := &Equals{}

	if expr == nil {
		return nil, errors.New("missing arguments in eq")
	}

	if field, ok := expr.Head.(atomiser.Symbol); !ok {
		return nil, fmt.Errorf("expected field name, got '%#v' instead", expr.Head)
	} else {
		cond.Field = string(field)
	}

	expr = expr.Tail
	if expr == nil {
		return nil, fmt.Errorf("missing value in (eq %s) expression", cond.Field)
	}

	cond.Value = fmt.Sprintf("%v", expr.Head)

	return cond, nil
}

func parseId(expr *chain.Cell) (Condition, error) {
	if expr == nil {
		return nil, fmt.Errorf("missing ID value in (id) expression")
	}

	id := new(Id)

	if id_str, ok := expr.Head.(atomiser.Symbol); !ok {
		return nil, fmt.Errorf("expected ID, got '%#v' instead", expr.Head)
	} else {
		parsed_id, err := strconv.ParseInt(string(id_str), 10, 64)
		if err != nil {
			return nil, fmt.Errorf("couldn't parse numeric ID in id expression")
		}
		*id = Id(parsed_id)
	}

	return id, nil
}
<commit_msg>use Car() and Cdr() instead of Head and Tail.<commit_after>package epos

import (
	"errors"
	"fmt"
	"github.com/feyeleanor/atomiser"
	"github.com/feyeleanor/chain"
	"strconv"
	"strings"
)

func Expression(s string) (Condition, error) {
	expr := atomiser.NewAtomiser(strings.NewReader(s)).ReadList()

	if expr == nil {
		return nil, fmt.Errorf("parsing '%s' failed", s)
	}

	return parseExpressionToCondition(expr)
}

func parseExpressionToCondition(expr *chain.Cell) (Condition, error) {
	sym, ok := expr.Car().(atomiser.Symbol)
	if !ok {
		return nil, fmt.Errorf("expected symbol, got '%v' instead", expr.Car())
	}

	sym = atomiser.Symbol(strings.ToLower(string(sym)))

	switch sym {
	case "and":
		return parseAnd(expr.Cdr())
	case "or":
		return parseOr(expr.Cdr())
	case "eq":
		return parseEqual(expr.Cdr())
	case "id":
		return parseId(expr.Cdr())
	}
	return nil, fmt.Errorf("unknown symbol '%s'", sym)
}

func parseAnd(expr *chain.Cell) (Condition, error) {
	cond := &And{}

	cur := expr
	for cur != nil {
		if subexpr, ok := cur.Car().(*chain.Cell); ok {
			if subcond, err := parseExpressionToCondition(subexpr); err != nil {
				return nil, err
			} else {
				*cond = append(*cond, subcond)
			}
		}
		cur = cur.Cdr()
	}

	if len(*cond) == 0 {
		return nil, errors.New("empty and expression")
	}

	return cond, nil
}

func parseOr(expr *chain.Cell) (Condition, error) {
	cond := &Or{}

	cur := expr
	for cur != nil {
		if subexpr, ok := cur.Car().(*chain.Cell); ok {
			if subcond, err := parseExpressionToCondition(subexpr); err != nil {
				return nil, err
			} else {
				*cond = append(*cond, subcond)
			}
		}
		cur = cur.Cdr()
	}

	if len(*cond) == 0 {
		return nil, errors.New("empty or expression")
	}

	return cond, nil
}

func parseEqual(expr *chain.Cell) (Condition, error) {
	cond := &Equals{}

	if expr == nil {
		return nil, errors.New("missing arguments in eq")
	}

	if field, ok := expr.Car().(atomiser.Symbol); !ok {
		return nil, fmt.Errorf("expected field name, got '%#v' instead", expr.Car())
	} else {
		cond.Field = string(field)
	}

	expr = expr.Cdr()
	if expr == nil {
		return nil, fmt.Errorf("missing value in (eq %s) expression", cond.Field)
	}

	cond.Value = fmt.Sprintf("%v", expr.Car())

	return cond, nil
}

func parseId(expr *chain.Cell) (Condition, error) {
	if expr == nil {
		return nil, fmt.Errorf("missing ID value in (id) expression")
	}

	id := new(Id)

	if id_str, ok := expr.Car().(atomiser.Symbol); !ok {
		return nil, fmt.Errorf("expected ID, got '%#v' instead", expr.Car())
	} else {
		parsed_id, err := strconv.ParseInt(string(id_str), 10, 64)
		if err != nil {
			return nil, fmt.Errorf("couldn't parse numeric ID in id expression")
		}
		*id = Id(parsed_id)
	}

	return id, nil
}
<|endoftext|>


<commit_before>package tracking

import (
	"encoding/json"
	"net/http"
	"os"
	"fmt"
	"time"

	log "github.com/Sirupsen/logrus"
	"gopkg.in/mgo.v2"
)

// Configuration holds the settings for connecting to outside resources.
type Configuration struct {
	DataFeed       string
	UpdateInterval int
	MongoURL       string
	MongoPort      string
}

// App holds references to Mongo resources.
type App struct {
	Session  *mgo.Session
	Updates  *mgo.Collection
	Vehicles *mgo.Collection
	Routes   *mgo.Collection
	Stops    *mgo.Collection
}

func InitConfig() *Configuration {
	// Read app configuration file
	config, err := readConfiguration("conf.json")
	if err != nil {
		log.Fatalf("error reading configuration file: %v", err)
	}

	return config
}

func InitApp(Config *Configuration) *App {
	// Connect to MongoDB
	session, err := mgo.Dial(Config.MongoURL + ":" + Config.MongoPort)
	if err != nil {
		log.Fatalf("mongoDB connection failed: %v", err)
	}
	// Create Shuttles object to store database session and collections
	app := App{
		session,
		session.DB("shuttle_tracking").C("updates"),
		session.DB("shuttle_tracking").C("vehicles"),
		session.DB("shuttle_tracking").C("routes"),
		session.DB("shuttle_tracking").C("stops"),
	}

	// Read vehicle configuration file
	serr := readseedConfiguration("seed/vehicle_seed.json", &app)
	if serr != nil {
		log.Fatalf("error reading vehicle configuration file: %v", serr)
	}

	return &app
}

func readConfiguration(fileName string) (*Configuration, error) {
	// Open config file and decode JSON to Configuration struct
	file, err := os.Open(fileName)
	if err != nil {
		return nil, err
	}
	decoder := json.NewDecoder(file)
	config := Configuration{}
	if err := decoder.Decode(&config); err != nil {
		return nil, err
	}
	return &config, nil
}

//readseedConfiguration adds a new vehicle to the database from seed.
func readseedConfiguration(fileName string, app *App) error {

	// Open seed_vehicle config file and decode JSON to app struct
	file, err := os.Open(fileName)
	//error handling
	if err != nil {
		return err
	}
	//create a decoder for a file
	fileread := json.NewDecoder(file)
	//decode file into string

	//calling vehicles from vehicles.go
	Vehicles := []Vehicle{}

	//create map to hold variables
	var vehicles_map map[string][]map[string]interface{}

	//call decode on fileread to place items into map
	if err := fileread.Decode(&vehicles_map); err!= nil{
		return err
	}

	for i := range vehicles_map["Vehicles"]{
		item := vehicles_map["Vehicles"][i]
		VehicleID, _ := item["VehicleID"].(string)
		VehicleName, _ := item["VehicleName"].(string)
		vehicle := Vehicle{VehicleID, VehicleName, time.Now(), time.Now()}
		Vehicles = append(Vehicles, vehicle)
	}

	for j := range Vehicles{
		err = app.Vehicles.Insert(&Vehicles[j])
		if err != nil {
		return err
		}
		fmt.Println("%v", Vehicles[j])
	}

	return nil
}

func WriteJSON(w http.ResponseWriter, data interface{}) error {
	w.Header().Set("Content-Type", "application/json")
	b, err := json.MarshalIndent(data, "", " ")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return err
	}
	w.Write(b)
	return nil
}
<commit_msg>gofmt + camelCase a function.<commit_after>package tracking

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"

	log "github.com/Sirupsen/logrus"
	"gopkg.in/mgo.v2"
)

// Configuration holds the settings for connecting to outside resources.
type Configuration struct {
	DataFeed       string
	UpdateInterval int
	MongoURL       string
	MongoPort      string
}

// App holds references to Mongo resources.
type App struct {
	Session  *mgo.Session
	Updates  *mgo.Collection
	Vehicles *mgo.Collection
	Routes   *mgo.Collection
	Stops    *mgo.Collection
}

func InitConfig() *Configuration {
	// Read app configuration file
	config, err := readConfiguration("conf.json")
	if err != nil {
		log.Fatalf("error reading configuration file: %v", err)
	}

	return config
}

func InitApp(Config *Configuration) *App {
	// Connect to MongoDB
	session, err := mgo.Dial(Config.MongoURL + ":" + Config.MongoPort)
	if err != nil {
		log.Fatalf("mongoDB connection failed: %v", err)
	}
	// Create Shuttles object to store database session and collections
	app := App{
		session,
		session.DB("shuttle_tracking").C("updates"),
		session.DB("shuttle_tracking").C("vehicles"),
		session.DB("shuttle_tracking").C("routes"),
		session.DB("shuttle_tracking").C("stops"),
	}

	// Read vehicle configuration file
	serr := readSeedConfiguration("seed/vehicle_seed.json", &app)
	if serr != nil {
		log.Fatalf("error reading vehicle configuration file: %v", serr)
	}

	return &app
}

func readConfiguration(fileName string) (*Configuration, error) {
	// Open config file and decode JSON to Configuration struct
	file, err := os.Open(fileName)
	if err != nil {
		return nil, err
	}
	decoder := json.NewDecoder(file)
	config := Configuration{}
	if err := decoder.Decode(&config); err != nil {
		return nil, err
	}
	return &config, nil
}

//readSeedConfiguration adds a new vehicle to the database from seed.
func readSeedConfiguration(fileName string, app *App) error {

	// Open seed_vehicle config file and decode JSON to app struct
	file, err := os.Open(fileName)
	//error handling
	if err != nil {
		return err
	}
	//create a decoder for a file
	fileread := json.NewDecoder(file)
	//decode file into string

	//calling vehicles from vehicles.go
	Vehicles := []Vehicle{}

	//create map to hold variables
	var vehicles_map map[string][]map[string]interface{}

	//call decode on fileread to place items into map
	if err := fileread.Decode(&vehicles_map); err != nil {
		return err
	}

	for i := range vehicles_map["Vehicles"] {
		item := vehicles_map["Vehicles"][i]
		VehicleID, _ := item["VehicleID"].(string)
		VehicleName, _ := item["VehicleName"].(string)
		vehicle := Vehicle{VehicleID, VehicleName, time.Now(), time.Now()}
		Vehicles = append(Vehicles, vehicle)
	}

	for j := range Vehicles {
		err = app.Vehicles.Insert(&Vehicles[j])
		if err != nil {
			return err
		}
		fmt.Println("%v", Vehicles[j])
	}

	return nil
}

func WriteJSON(w http.ResponseWriter, data interface{}) error {
	w.Header().Set("Content-Type", "application/json")
	b, err := json.MarshalIndent(data, "", " ")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return err
	}
	w.Write(b)
	return nil
}
<|endoftext|>


<commit_before>package functional

import (
    "fmt"
    "testing"
)

func TestNewInfiniteGenerator(t *testing.T) {

  var finished bool
  // fibonacci
  fib := NewGenerator(
      func(e Emitter) {
        a := 0
        b := 1
        for ptr := e.EmitPtr(); ptr != nil; ptr = e.EmitPtr() {
          p := ptr.(*int)
          *p = a
          e.Return(nil)
          a, b = b, a + b
        }
        finished = true
      })
  var results []int
  stream := Slice(fib, 0, 7)
  results, err := toIntArray(stream)
  if output := fmt.Sprintf("%v", results); output != "[0 1 1 2 3 5 8]"  {
    t.Errorf("Expected [0 1 1 2 3 5 8] got %v", output)
  }
  if !finished {
    t.Error("Generating function should complete on close.")
  }
  verifyDone(t, stream, new(int), err)
}

func TestNewFiniteGenerator(t *testing.T) {
  var finished bool
  stream := NewGenerator(
      func(e Emitter) {
        values := []int{1, 2, 5}
        for i := range values {
          ptr := e.EmitPtr()
          if ptr == nil {
            break
          }
          *ptr.(*int) = values[i]
          e.Return(nil)
        }
        finished = true
      })
  results, err := toIntArray(stream)
  if output := fmt.Sprintf("%v", results); output != "[1 2 5]" {
    t.Errorf("Expected [1 2 5] got %v", output)
  }
  if !finished {
    t.Error("Generating function should have completed.")
  }
  verifyDone(t, stream, new(int), err)
}

func TestEmptyGenerator(t *testing.T) {
  var finished bool
  stream := NewGenerator(func (e Emitter) { finished = true })
  results, err := toIntArray(stream)
  if output := fmt.Sprintf("%v", results); output != "[]" {
    t.Errorf("Expected [] got %v", output)
  }
  if !finished {
    t.Error("Generating function should have completed.")
  }
  verifyDone(t, stream, new(int), err)
}
<commit_msg>Add test for EmitAll.<commit_after>package functional

import (
    "fmt"
    "testing"
)

func TestNewInfiniteGenerator(t *testing.T) {

  var finished bool
  // fibonacci
  fib := NewGenerator(
      func(e Emitter) {
        a := 0
        b := 1
        for ptr := e.EmitPtr(); ptr != nil; ptr = e.EmitPtr() {
          p := ptr.(*int)
          *p = a
          e.Return(nil)
          a, b = b, a + b
        }
        finished = true
      })
  var results []int
  stream := Slice(fib, 0, 7)
  results, err := toIntArray(stream)
  if output := fmt.Sprintf("%v", results); output != "[0 1 1 2 3 5 8]"  {
    t.Errorf("Expected [0 1 1 2 3 5 8] got %v", output)
  }
  if !finished {
    t.Error("Generating function should complete on close.")
  }
  verifyDone(t, stream, new(int), err)
}

func TestNewFiniteGenerator(t *testing.T) {
  var finished bool
  stream := NewGenerator(
      func(e Emitter) {
        values := []int{1, 2, 5}
        for i := range values {
          ptr := e.EmitPtr()
          if ptr == nil {
            break
          }
          *ptr.(*int) = values[i]
          e.Return(nil)
        }
        finished = true
      })
  results, err := toIntArray(stream)
  if output := fmt.Sprintf("%v", results); output != "[1 2 5]" {
    t.Errorf("Expected [1 2 5] got %v", output)
  }
  if !finished {
    t.Error("Generating function should have completed.")
  }
  verifyDone(t, stream, new(int), err)
}

func TestEmptyGenerator(t *testing.T) {
  var finished bool
  stream := NewGenerator(func (e Emitter) { finished = true })
  results, err := toIntArray(stream)
  if output := fmt.Sprintf("%v", results); output != "[]" {
    t.Errorf("Expected [] got %v", output)
  }
  if !finished {
    t.Error("Generating function should have completed.")
  }
  verifyDone(t, stream, new(int), err)
}

func TestEmitAllClosed(t *testing.T) {
  s := Count()
  e := fakeEmitter{nil}
  if output := EmitAll(s, e); output != Done {
    t.Errorf("Expected Done, got %v", output)
  }
}

func TestEmitAllSuccess(t *testing.T) {
  s := xrange(0, 10)
  e := fakeEmitter{new(int)}
  if output := EmitAll(s, e); output != nil {
    t.Errorf("Expected nil, got %v", output)
  }
}

type fakeEmitter struct {
  ptr interface{}
}

func (e fakeEmitter) EmitPtr() interface{} {
  return e.ptr
}

func (e fakeEmitter) Return(err error) {
}

<|endoftext|>


<commit_before>package examples

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"testing"

	"github.com/pachyderm/pachyderm/src/client"
	pfsclient "github.com/pachyderm/pachyderm/src/client/pfs"
	"github.com/pachyderm/pachyderm/src/client/pkg/require"
)

func getPachClient(t testing.TB) *client.APIClient {
	client, err := client.NewFromAddress("0.0.0.0:30650")
	require.NoError(t, err)
	return client
}

func TestExampleTensorFlow(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration tests in short mode")
	}

	c := getPachClient(t)
	t.Parallel()

	cwd, err := os.Getwd()
	require.NoError(t, err)
	exampleDir := filepath.Join(cwd, "../../../doc/examples/tensor_flow")
	cmd := exec.Command("make", "test")
	cmd.Dir = exampleDir
	_, err = cmd.CombinedOutput()
	require.NoError(t, err)

	commitInfos, err := c.ListCommit(
		[]*pfsclient.Commit{{
			Repo: &pfsclient.Repo{"GoT_scripts"},
		}},
		nil,
		client.CommitTypeRead,
		client.CommitStatusAll,
		false,
	)
	require.NoError(t, err)
	require.Equal(t, 1, len(commitInfos))
	inputCommitID := commitInfos[0].Commit.ID

	// Wait until the GoT_generate job has finished
	commitInfos, err = c.FlushCommit([]*pfsclient.Commit{client.NewCommit("GoT_scripts", inputCommitID)}, nil)
	require.NoError(t, err)
	require.Equal(t, 3, len(commitInfos))

	repos := []interface{}{"GoT_train", "GoT_generate", "GoT_scripts"}
	var generateCommitID string
	for _, commitInfo := range commitInfos {
		require.EqualOneOf(t, repos, commitInfo.Commit.Repo.Name)
		if commitInfo.Commit.Repo.Name == "GoT_generate" {
			generateCommitID = commitInfo.Commit.ID
		}
	}

	// Make sure the final output is non zero
	var buffer bytes.Buffer
	require.NoError(t, c.GetFile("GoT_generate", generateCommitID, "new_script.txt", 0, 0, "", false, nil, &buffer))
	if buffer.Len() < 100 {
		t.Fatalf("Output GoT script is too small (has len=%v)", buffer.Len())
	}
	require.NoError(t, c.DeleteRepo("GoT_generate", false))
	require.NoError(t, c.DeleteRepo("GoT_train", false))
	require.NoError(t, c.DeleteRepo("GoT_scripts", false))
}

func TestFruitStand(t *testing.T) {

	if testing.Short() {
		t.Skip("Skipping integration tests in short mode")
	}

	c := getPachClient(t)
	t.Parallel()

	require.NoError(t, c.CreateRepo("data"))
	repoInfos, err := c.ListRepo(nil)
	require.NoError(t, err)
	var repoNames []interface{}
	for _, repoInfo := range repoInfos {
		repoNames = append(repoNames, repoInfo.Repo.Name)
	}
	require.OneOfEquals(t, "data", repoNames)

	raw, err := exec.Command(
		"git",
		"log",
		"--format=%H",
	).CombinedOutput()
	require.NoError(t, err)
	lines := strings.Split(string(raw), "\n")
	require.NotEqual(t, 0, len(lines))
	currentCodeCommitID := lines[0]

	cmd := exec.Command(
		"pachctl",
		"put-file",
		"data",
		"master",
		"sales",
		"-c",
		"-f",
		fmt.Sprintf("https://raw.githubusercontent.com/pachyderm/pachyderm/%v/doc/examples/fruit_stand/set1.txt", currentCodeCommitID),
	)
	_, err = cmd.CombinedOutput()
	require.NoError(t, err)

	commitInfos, err := c.ListCommit(
		[]*pfsclient.Commit{{
			Repo: &pfsclient.Repo{"data"},
		}},
		nil,
		client.CommitTypeRead,
		client.CommitStatusNormal,
		false,
	)
	require.Equal(t, 1, len(commitInfos))
	commit := commitInfos[0].Commit

	var buffer bytes.Buffer
	require.NoError(t, c.GetFile("data", commit.ID, "sales", 0, 0, "", false, nil, &buffer))
	lines = strings.Split(buffer.String(), "\n")
	if len(lines) < 100 {
		t.Fatalf("Sales file has too few lines (%v)\n", len(lines))
	}

	pipelineURL := fmt.Sprintf("https://raw.githubusercontent.com/pachyderm/pachyderm/%v/doc/examples/fruit_stand/pipeline.json", currentCodeCommitID)
	cmd = exec.Command(
		"pachctl",
		"create-pipeline",
		"-f",
		pipelineURL,
	)
	raw, err = cmd.CombinedOutput()
	fmt.Printf("pipeline URL (%v), raw: %v\n", pipelineURL, string(raw))
	require.NoError(t, err)

	repoInfos, err = c.ListRepo(nil)
	require.NoError(t, err)
	repoNames = []interface{}{}
	for _, repoInfo := range repoInfos {
		repoNames = append(repoNames, repoInfo.Repo.Name)
	}
	require.OneOfEquals(t, "sum", repoNames)
	require.OneOfEquals(t, "filter", repoNames)
	require.OneOfEquals(t, "data", repoNames)

	commitInfos, err = c.FlushCommit([]*pfsclient.Commit{client.NewCommit("data", commit.ID)}, nil)
	require.NoError(t, err)
	require.Equal(t, 3, len(commitInfos))

	commitInfos, err = c.ListCommit(
		[]*pfsclient.Commit{{
			Repo: &pfsclient.Repo{"sum"},
		}},
		nil,
		client.CommitTypeRead,
		client.CommitStatusNormal,
		false,
	)
	require.NoError(t, err)
	require.Equal(t, 1, len(commitInfos))

	buffer.Reset()
	require.NoError(t, c.GetFile("sum", commitInfos[0].Commit.ID, "apple", 0, 0, "", false, nil, &buffer))
	require.NotNil(t, buffer)
	firstCount, err := strconv.ParseInt(strings.TrimRight(buffer.String(), "\n"), 10, 0)
	require.NoError(t, err)
	if firstCount < 100 {
		t.Fatalf("Wrong sum for apple (%i) ... too low\n", firstCount)
	}

	// Add more data to input

	cmd = exec.Command(
		"pachctl",
		"put-file",
		"data",
		"master",
		"sales",
		"-c",
		"-f",
		"https://raw.githubusercontent.com/pachyderm/pachyderm/master/examples/fruit_stand/set2.txt",
	)
	_, err = cmd.Output()
	require.NoError(t, err)

	// Flush commit!
	commitInfos, err = c.ListCommit(
		[]*pfsclient.Commit{{
			Repo: &pfsclient.Repo{"data"},
		}},
		nil,
		client.CommitTypeRead,
		client.CommitStatusAll,
		false,
	)
	require.NoError(t, err)
	require.Equal(t, 2, len(commitInfos))

	commitInfos, err = c.FlushCommit([]*pfsclient.Commit{client.NewCommit("data", commitInfos[1].Commit.ID)}, nil)
	require.NoError(t, err)
	require.Equal(t, 3, len(commitInfos))

	commitInfos, err = c.ListCommit(
		[]*pfsclient.Commit{{
			Repo: &pfsclient.Repo{"sum"},
		}},
		nil,
		client.CommitTypeRead,
		client.CommitStatusNormal,
		false,
	)
	require.NoError(t, err)
	require.Equal(t, 2, len(commitInfos))

	buffer.Reset()
	require.NoError(t, c.GetFile("sum", commitInfos[1].Commit.ID, "apple", 0, 0, "", false, nil, &buffer))
	require.NotNil(t, buffer)
	secondCount, err := strconv.ParseInt(strings.TrimRight(buffer.String(), "\n"), 10, 0)
	require.NoError(t, err)
	if firstCount > secondCount {
		t.Fatalf("Second sum (%v) is smaller than first (%v)\n", secondCount, firstCount)
	}

	require.NoError(t, c.DeleteRepo("sum", false))
	require.NoError(t, c.DeleteRepo("filter", false))
	require.NoError(t, c.DeleteRepo("data", false))
}
<commit_msg>Use local pipeline manifests for TestFruitStand<commit_after>package examples

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"testing"

	"github.com/pachyderm/pachyderm/src/client"
	pfsclient "github.com/pachyderm/pachyderm/src/client/pfs"
	"github.com/pachyderm/pachyderm/src/client/pkg/require"
)

func getPachClient(t testing.TB) *client.APIClient {
	client, err := client.NewFromAddress("0.0.0.0:30650")
	require.NoError(t, err)
	return client
}

func TestExampleTensorFlow(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration tests in short mode")
	}

	c := getPachClient(t)
	t.Parallel()

	cwd, err := os.Getwd()
	require.NoError(t, err)
	exampleDir := filepath.Join(cwd, "../../../doc/examples/tensor_flow")
	cmd := exec.Command("make", "test")
	cmd.Dir = exampleDir
	_, err = cmd.CombinedOutput()
	require.NoError(t, err)

	commitInfos, err := c.ListCommit(
		[]*pfsclient.Commit{{
			Repo: &pfsclient.Repo{"GoT_scripts"},
		}},
		nil,
		client.CommitTypeRead,
		client.CommitStatusAll,
		false,
	)
	require.NoError(t, err)
	require.Equal(t, 1, len(commitInfos))
	inputCommitID := commitInfos[0].Commit.ID

	// Wait until the GoT_generate job has finished
	commitInfos, err = c.FlushCommit([]*pfsclient.Commit{client.NewCommit("GoT_scripts", inputCommitID)}, nil)
	require.NoError(t, err)
	require.Equal(t, 3, len(commitInfos))

	repos := []interface{}{"GoT_train", "GoT_generate", "GoT_scripts"}
	var generateCommitID string
	for _, commitInfo := range commitInfos {
		require.EqualOneOf(t, repos, commitInfo.Commit.Repo.Name)
		if commitInfo.Commit.Repo.Name == "GoT_generate" {
			generateCommitID = commitInfo.Commit.ID
		}
	}

	// Make sure the final output is non zero
	var buffer bytes.Buffer
	require.NoError(t, c.GetFile("GoT_generate", generateCommitID, "new_script.txt", 0, 0, "", false, nil, &buffer))
	if buffer.Len() < 100 {
		t.Fatalf("Output GoT script is too small (has len=%v)", buffer.Len())
	}
	require.NoError(t, c.DeleteRepo("GoT_generate", false))
	require.NoError(t, c.DeleteRepo("GoT_train", false))
	require.NoError(t, c.DeleteRepo("GoT_scripts", false))
}

func TestFruitStand(t *testing.T) {

	if testing.Short() {
		t.Skip("Skipping integration tests in short mode")
	}

	c := getPachClient(t)
	t.Parallel()

	require.NoError(t, c.CreateRepo("data"))
	repoInfos, err := c.ListRepo(nil)
	require.NoError(t, err)
	var repoNames []interface{}
	for _, repoInfo := range repoInfos {
		repoNames = append(repoNames, repoInfo.Repo.Name)
	}
	require.OneOfEquals(t, "data", repoNames)

	cmd := exec.Command(
		"pachctl",
		"put-file",
		"data",
		"master",
		"sales",
		"-c",
		"-f",
		"../../../doc/examples/fruit_stand/set1.txt",
	)
	_, err = cmd.CombinedOutput()
	require.NoError(t, err)

	commitInfos, err := c.ListCommit(
		[]*pfsclient.Commit{{
			Repo: &pfsclient.Repo{"data"},
		}},
		nil,
		client.CommitTypeRead,
		client.CommitStatusNormal,
		false,
	)
	require.Equal(t, 1, len(commitInfos))
	commit := commitInfos[0].Commit

	var buffer bytes.Buffer
	require.NoError(t, c.GetFile("data", commit.ID, "sales", 0, 0, "", false, nil, &buffer))
	lines := strings.Split(buffer.String(), "\n")
	if len(lines) < 100 {
		t.Fatalf("Sales file has too few lines (%v)\n", len(lines))
	}

	cmd = exec.Command(
		"pachctl",
		"create-pipeline",
		"-f",
		"../../../doc/examples/fruit_stand/pipeline.json",
	)
	raw, err := cmd.CombinedOutput()
	fmt.Printf("raw: %v\n", string(raw))
	require.NoError(t, err)

	repoInfos, err = c.ListRepo(nil)
	require.NoError(t, err)
	repoNames = []interface{}{}
	for _, repoInfo := range repoInfos {
		repoNames = append(repoNames, repoInfo.Repo.Name)
	}
	require.OneOfEquals(t, "sum", repoNames)
	require.OneOfEquals(t, "filter", repoNames)
	require.OneOfEquals(t, "data", repoNames)

	commitInfos, err = c.FlushCommit([]*pfsclient.Commit{client.NewCommit("data", commit.ID)}, nil)
	require.NoError(t, err)
	require.Equal(t, 3, len(commitInfos))

	commitInfos, err = c.ListCommit(
		[]*pfsclient.Commit{{
			Repo: &pfsclient.Repo{"sum"},
		}},
		nil,
		client.CommitTypeRead,
		client.CommitStatusNormal,
		false,
	)
	require.NoError(t, err)
	require.Equal(t, 1, len(commitInfos))

	buffer.Reset()
	require.NoError(t, c.GetFile("sum", commitInfos[0].Commit.ID, "apple", 0, 0, "", false, nil, &buffer))
	require.NotNil(t, buffer)
	firstCount, err := strconv.ParseInt(strings.TrimRight(buffer.String(), "\n"), 10, 0)
	require.NoError(t, err)
	if firstCount < 100 {
		t.Fatalf("Wrong sum for apple (%i) ... too low\n", firstCount)
	}

	// Add more data to input

	cmd = exec.Command(
		"pachctl",
		"put-file",
		"data",
		"master",
		"sales",
		"-c",
		"-f",
		"https://raw.githubusercontent.com/pachyderm/pachyderm/master/examples/fruit_stand/set2.txt",
	)
	_, err = cmd.Output()
	require.NoError(t, err)

	// Flush commit!
	commitInfos, err = c.ListCommit(
		[]*pfsclient.Commit{{
			Repo: &pfsclient.Repo{"data"},
		}},
		nil,
		client.CommitTypeRead,
		client.CommitStatusAll,
		false,
	)
	require.NoError(t, err)
	require.Equal(t, 2, len(commitInfos))

	commitInfos, err = c.FlushCommit([]*pfsclient.Commit{client.NewCommit("data", commitInfos[1].Commit.ID)}, nil)
	require.NoError(t, err)
	require.Equal(t, 3, len(commitInfos))

	commitInfos, err = c.ListCommit(
		[]*pfsclient.Commit{{
			Repo: &pfsclient.Repo{"sum"},
		}},
		nil,
		client.CommitTypeRead,
		client.CommitStatusNormal,
		false,
	)
	require.NoError(t, err)
	require.Equal(t, 2, len(commitInfos))

	buffer.Reset()
	require.NoError(t, c.GetFile("sum", commitInfos[1].Commit.ID, "apple", 0, 0, "", false, nil, &buffer))
	require.NotNil(t, buffer)
	secondCount, err := strconv.ParseInt(strings.TrimRight(buffer.String(), "\n"), 10, 0)
	require.NoError(t, err)
	if firstCount > secondCount {
		t.Fatalf("Second sum (%v) is smaller than first (%v)\n", secondCount, firstCount)
	}

	require.NoError(t, c.DeleteRepo("sum", false))
	require.NoError(t, c.DeleteRepo("filter", false))
	require.NoError(t, c.DeleteRepo("data", false))
}
<|endoftext|>


<commit_before>package server

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/fatih/camelcase"
	"github.com/golang/groupcache"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/sirupsen/logrus"
)

var groupCacheStatFields = []string{
	"Gets",
	"CacheHits",
	"PeerLoads",
	"PeerErrors",
	"Loads",
	"LoadsDeduped",
	"LocalLoads",
	"LocalLoadErrs",
	"ServerRequests",
}

type cacheStats struct {
	cacheName    string
	descriptions map[string]*prometheus.Desc
	*groupcache.Stats
}

func NewCacheStats(cacheName string, groupCacheStats *groupcache.Stats) *cacheStats {
	c := &cacheStats{cacheName, make(map[string]*prometheus.Desc), groupCacheStats}
	if err := prometheus.Register(c); err != nil {
		logrus.Infof("error registering prometheus metric: %v", err)
	}
	return c
}

func (c *cacheStats) Describe(ch chan<- *prometheus.Desc) {
	for _, statFieldName := range groupCacheStatFields {
		statName := c.statName(statFieldName)
		desc := prometheus.NewDesc(
			statName,
			fmt.Sprintf("groupcache %v", statFieldName),
			[]string{},
			nil,
		)
		c.descriptions[statName] = desc
		ch <- desc
	}
}

func (c *cacheStats) Collect(ch chan<- prometheus.Metric) {
	for _, statFieldName := range groupCacheStatFields {
		r := reflect.ValueOf(c)
		value := reflect.Indirect(r).FieldByName(statFieldName)
		metric, err := prometheus.NewConstMetric(
			c.descriptions[c.statName(statFieldName)],
			prometheus.GaugeValue,
			float64(value.Int()),
		)
		if err != nil {
			logrus.Infof("error reporting prometheus cache metric %v: %v", c.statName(statFieldName), err)
		} else {
			ch <- metric
		}
	}
}

func (c *cacheStats) statName(fieldName string) string {
	var tokens []string
	for _, token := range camelcase.Split(fieldName) {
		tokens = append(tokens, strings.ToLower(token))
	}
	groupCacheStatName := strings.Join(tokens, "_")

	return fmt.Sprintf("pachd_cache_%v_%v_gauge", c.cacheName, groupCacheStatName)
}
<commit_msg>Fix cache stats namespace<commit_after>package server

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/fatih/camelcase"
	"github.com/golang/groupcache"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/sirupsen/logrus"
)

var groupCacheStatFields = []string{
	"Gets",
	"CacheHits",
	"PeerLoads",
	"PeerErrors",
	"Loads",
	"LoadsDeduped",
	"LocalLoads",
	"LocalLoadErrs",
	"ServerRequests",
}

type cacheStats struct {
	cacheName    string
	descriptions map[string]*prometheus.Desc
	*groupcache.Stats
}

func NewCacheStats(cacheName string, groupCacheStats *groupcache.Stats) *cacheStats {
	c := &cacheStats{cacheName, make(map[string]*prometheus.Desc), groupCacheStats}
	if err := prometheus.Register(c); err != nil {
		logrus.Infof("error registering prometheus metric: %v", err)
	}
	return c
}

func (c *cacheStats) Describe(ch chan<- *prometheus.Desc) {
	for _, statFieldName := range groupCacheStatFields {
		statName := c.statName(statFieldName)
		desc := prometheus.NewDesc(
			statName,
			fmt.Sprintf("groupcache %v", statFieldName),
			[]string{},
			nil,
		)
		c.descriptions[statName] = desc
		ch <- desc
	}
}

func (c *cacheStats) Collect(ch chan<- prometheus.Metric) {
	for _, statFieldName := range groupCacheStatFields {
		r := reflect.ValueOf(c)
		value := reflect.Indirect(r).FieldByName(statFieldName)
		metric, err := prometheus.NewConstMetric(
			c.descriptions[c.statName(statFieldName)],
			prometheus.GaugeValue,
			float64(value.Int()),
		)
		if err != nil {
			logrus.Infof("error reporting prometheus cache metric %v: %v", c.statName(statFieldName), err)
		} else {
			ch <- metric
		}
	}
}

func (c *cacheStats) statName(fieldName string) string {
	var tokens []string
	for _, token := range camelcase.Split(fieldName) {
		tokens = append(tokens, strings.ToLower(token))
	}
	groupCacheStatName := strings.Join(tokens, "_")

	return fmt.Sprintf("pachyderm_pachd_cache_%v_%v_gauge", c.cacheName, groupCacheStatName)
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Knative Authors

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

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

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

package testing

import (
	istiov1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3"
	admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
	appsv1 "k8s.io/api/apps/v1"
	autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/runtime"
	fakekubeclientset "k8s.io/client-go/kubernetes/fake"
	admissionlisters "k8s.io/client-go/listers/admissionregistration/v1beta1"
	appsv1listers "k8s.io/client-go/listers/apps/v1"
	autoscalingv2beta1listers "k8s.io/client-go/listers/autoscaling/v2beta1"
	corev1listers "k8s.io/client-go/listers/core/v1"
	"k8s.io/client-go/tools/cache"
	fakeistioclientset "knative.dev/pkg/client/istio/clientset/versioned/fake"
	istiolisters "knative.dev/pkg/client/istio/listers/networking/v1alpha3"
	"knative.dev/pkg/reconciler/testing"
	pkgtesting "knative.dev/pkg/testing"
)

var clientSetSchemes = []func(*runtime.Scheme) error{
	fakekubeclientset.AddToScheme,
	fakeistioclientset.AddToScheme,
	autoscalingv2beta1.AddToScheme,
	pkgtesting.AddToScheme,
}

// Listers is used to synthesize informer-style Listers from fixed lists of resources in tests.
type Listers struct {
	sorter testing.ObjectSorter
}

// NewListers constructs a Listers from a collection of objects.
func NewListers(objs []runtime.Object) Listers {
	scheme := NewScheme()

	ls := Listers{
		sorter: testing.NewObjectSorter(scheme),
	}

	ls.sorter.AddObjects(objs...)

	return ls
}

// NewScheme constructs a scheme from the set of client schemes supported by this package.
func NewScheme() *runtime.Scheme {
	scheme := runtime.NewScheme()

	for _, addTo := range clientSetSchemes {
		addTo(scheme)
	}
	return scheme
}

// NewScheme constructs a scheme from the set of client schemes supported by this lister.
func (*Listers) NewScheme() *runtime.Scheme {
	return NewScheme()
}

// IndexerFor returns the indexer for the given object.
func (l *Listers) IndexerFor(obj runtime.Object) cache.Indexer {
	return l.sorter.IndexerForObjectType(obj)
}

// GetKubeObjects filters the Listers initial list of objects to built-in types
func (l *Listers) GetKubeObjects() []runtime.Object {
	return l.sorter.ObjectsForSchemeFunc(fakekubeclientset.AddToScheme)
}

// GetIstioObjects filters the Listers initial list of objects to types defined in knative/pkg
func (l *Listers) GetIstioObjects() []runtime.Object {
	return l.sorter.ObjectsForSchemeFunc(fakeistioclientset.AddToScheme)
}

// GetIstioObjects filters the Listers initial list of objects to types defined in knative/pkg
func (l *Listers) GetTestObjects() []runtime.Object {
	return l.sorter.ObjectsForSchemeFunc(pkgtesting.AddToScheme)
}

// GetHorizontalPodAutoscalerLister gets lister for HorizontalPodAutoscaler resources.
func (l *Listers) GetHorizontalPodAutoscalerLister() autoscalingv2beta1listers.HorizontalPodAutoscalerLister {
	return autoscalingv2beta1listers.NewHorizontalPodAutoscalerLister(l.IndexerFor(&autoscalingv2beta1.HorizontalPodAutoscaler{}))
}

// GetVirtualServiceLister gets lister for Istio VirtualService resource.
func (l *Listers) GetVirtualServiceLister() istiolisters.VirtualServiceLister {
	return istiolisters.NewVirtualServiceLister(l.IndexerFor(&istiov1alpha3.VirtualService{}))
}

// GetGatewayLister gets lister for Istio Gateway resource.
func (l *Listers) GetGatewayLister() istiolisters.GatewayLister {
	return istiolisters.NewGatewayLister(l.IndexerFor(&istiov1alpha3.Gateway{}))
}

// GetDeploymentLister gets lister for K8s Deployment resource.
func (l *Listers) GetDeploymentLister() appsv1listers.DeploymentLister {
	return appsv1listers.NewDeploymentLister(l.IndexerFor(&appsv1.Deployment{}))
}

// GetK8sServiceLister gets lister for K8s Service resource.
func (l *Listers) GetK8sServiceLister() corev1listers.ServiceLister {
	return corev1listers.NewServiceLister(l.IndexerFor(&corev1.Service{}))
}

// GetEndpointsLister gets lister for K8s Endpoints resource.
func (l *Listers) GetEndpointsLister() corev1listers.EndpointsLister {
	return corev1listers.NewEndpointsLister(l.IndexerFor(&corev1.Endpoints{}))
}

// GetSecretLister gets lister for K8s Secret resource.
func (l *Listers) GetSecretLister() corev1listers.SecretLister {
	return corev1listers.NewSecretLister(l.IndexerFor(&corev1.Secret{}))
}

// GetConfigMapLister gets lister for K8s ConfigMap resource.
func (l *Listers) GetConfigMapLister() corev1listers.ConfigMapLister {
	return corev1listers.NewConfigMapLister(l.IndexerFor(&corev1.ConfigMap{}))
}

// GetNamespaceLister gets lister for Namespace resource.
func (l *Listers) GetNamespaceLister() corev1listers.NamespaceLister {
	return corev1listers.NewNamespaceLister(l.IndexerFor(&corev1.Namespace{}))
}

// GetMutatingWebhookConfigurationLister gets lister for K8s MutatingWebhookConfiguration resource.
func (l *Listers) GetMutatingWebhookConfigurationLister() admissionlisters.MutatingWebhookConfigurationLister {
	return admissionlisters.NewMutatingWebhookConfigurationLister(l.IndexerFor(&admissionregistrationv1beta1.MutatingWebhookConfiguration{}))
}

// GetValidatingWebhookConfigurationLister gets lister for K8s ValidatingWebhookConfiguration resource.
func (l *Listers) GetValidatingWebhookConfigurationLister() admissionlisters.ValidatingWebhookConfigurationLister {
	return admissionlisters.NewValidatingWebhookConfigurationLister(l.IndexerFor(&admissionregistrationv1beta1.ValidatingWebhookConfiguration{}))
}
<commit_msg>fix comment, followup to 911 (#912)<commit_after>/*
Copyright 2019 The Knative Authors

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

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

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

package testing

import (
	istiov1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3"
	admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
	appsv1 "k8s.io/api/apps/v1"
	autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/runtime"
	fakekubeclientset "k8s.io/client-go/kubernetes/fake"
	admissionlisters "k8s.io/client-go/listers/admissionregistration/v1beta1"
	appsv1listers "k8s.io/client-go/listers/apps/v1"
	autoscalingv2beta1listers "k8s.io/client-go/listers/autoscaling/v2beta1"
	corev1listers "k8s.io/client-go/listers/core/v1"
	"k8s.io/client-go/tools/cache"
	fakeistioclientset "knative.dev/pkg/client/istio/clientset/versioned/fake"
	istiolisters "knative.dev/pkg/client/istio/listers/networking/v1alpha3"
	"knative.dev/pkg/reconciler/testing"
	pkgtesting "knative.dev/pkg/testing"
)

var clientSetSchemes = []func(*runtime.Scheme) error{
	fakekubeclientset.AddToScheme,
	fakeistioclientset.AddToScheme,
	autoscalingv2beta1.AddToScheme,
	pkgtesting.AddToScheme,
}

// Listers is used to synthesize informer-style Listers from fixed lists of resources in tests.
type Listers struct {
	sorter testing.ObjectSorter
}

// NewListers constructs a Listers from a collection of objects.
func NewListers(objs []runtime.Object) Listers {
	scheme := NewScheme()

	ls := Listers{
		sorter: testing.NewObjectSorter(scheme),
	}

	ls.sorter.AddObjects(objs...)

	return ls
}

// NewScheme constructs a scheme from the set of client schemes supported by this package.
func NewScheme() *runtime.Scheme {
	scheme := runtime.NewScheme()

	for _, addTo := range clientSetSchemes {
		addTo(scheme)
	}
	return scheme
}

// NewScheme constructs a scheme from the set of client schemes supported by this lister.
func (*Listers) NewScheme() *runtime.Scheme {
	return NewScheme()
}

// IndexerFor returns the indexer for the given object.
func (l *Listers) IndexerFor(obj runtime.Object) cache.Indexer {
	return l.sorter.IndexerForObjectType(obj)
}

// GetKubeObjects filters the Listers initial list of objects to built-in types
func (l *Listers) GetKubeObjects() []runtime.Object {
	return l.sorter.ObjectsForSchemeFunc(fakekubeclientset.AddToScheme)
}

// GetIstioObjects filters the Listers initial list of objects to types defined in knative/pkg
func (l *Listers) GetIstioObjects() []runtime.Object {
	return l.sorter.ObjectsForSchemeFunc(fakeistioclientset.AddToScheme)
}

// GetTestObjects filters the Lister's initial list of objects to types defined in knative/pkg/testing
func (l *Listers) GetTestObjects() []runtime.Object {
	return l.sorter.ObjectsForSchemeFunc(pkgtesting.AddToScheme)
}

// GetHorizontalPodAutoscalerLister gets lister for HorizontalPodAutoscaler resources.
func (l *Listers) GetHorizontalPodAutoscalerLister() autoscalingv2beta1listers.HorizontalPodAutoscalerLister {
	return autoscalingv2beta1listers.NewHorizontalPodAutoscalerLister(l.IndexerFor(&autoscalingv2beta1.HorizontalPodAutoscaler{}))
}

// GetVirtualServiceLister gets lister for Istio VirtualService resource.
func (l *Listers) GetVirtualServiceLister() istiolisters.VirtualServiceLister {
	return istiolisters.NewVirtualServiceLister(l.IndexerFor(&istiov1alpha3.VirtualService{}))
}

// GetGatewayLister gets lister for Istio Gateway resource.
func (l *Listers) GetGatewayLister() istiolisters.GatewayLister {
	return istiolisters.NewGatewayLister(l.IndexerFor(&istiov1alpha3.Gateway{}))
}

// GetDeploymentLister gets lister for K8s Deployment resource.
func (l *Listers) GetDeploymentLister() appsv1listers.DeploymentLister {
	return appsv1listers.NewDeploymentLister(l.IndexerFor(&appsv1.Deployment{}))
}

// GetK8sServiceLister gets lister for K8s Service resource.
func (l *Listers) GetK8sServiceLister() corev1listers.ServiceLister {
	return corev1listers.NewServiceLister(l.IndexerFor(&corev1.Service{}))
}

// GetEndpointsLister gets lister for K8s Endpoints resource.
func (l *Listers) GetEndpointsLister() corev1listers.EndpointsLister {
	return corev1listers.NewEndpointsLister(l.IndexerFor(&corev1.Endpoints{}))
}

// GetSecretLister gets lister for K8s Secret resource.
func (l *Listers) GetSecretLister() corev1listers.SecretLister {
	return corev1listers.NewSecretLister(l.IndexerFor(&corev1.Secret{}))
}

// GetConfigMapLister gets lister for K8s ConfigMap resource.
func (l *Listers) GetConfigMapLister() corev1listers.ConfigMapLister {
	return corev1listers.NewConfigMapLister(l.IndexerFor(&corev1.ConfigMap{}))
}

// GetNamespaceLister gets lister for Namespace resource.
func (l *Listers) GetNamespaceLister() corev1listers.NamespaceLister {
	return corev1listers.NewNamespaceLister(l.IndexerFor(&corev1.Namespace{}))
}

// GetMutatingWebhookConfigurationLister gets lister for K8s MutatingWebhookConfiguration resource.
func (l *Listers) GetMutatingWebhookConfigurationLister() admissionlisters.MutatingWebhookConfigurationLister {
	return admissionlisters.NewMutatingWebhookConfigurationLister(l.IndexerFor(&admissionregistrationv1beta1.MutatingWebhookConfiguration{}))
}

// GetValidatingWebhookConfigurationLister gets lister for K8s ValidatingWebhookConfiguration resource.
func (l *Listers) GetValidatingWebhookConfigurationLister() admissionlisters.ValidatingWebhookConfigurationLister {
	return admissionlisters.NewValidatingWebhookConfigurationLister(l.IndexerFor(&admissionregistrationv1beta1.ValidatingWebhookConfiguration{}))
}
<|endoftext|>


<commit_before>package timebatchdb

import (
	"database/sql"
	"errors"
)

var (
	//ErrorDatabaseDriver is called when the database driver given when initializing is unrecognized
	ErrorDatabaseDriver = errors.New("Database driver not supported")
	//ErrorDatabaseCorrupted is returned when there is data loss or inconsistency in the database
	ErrorDatabaseCorrupted = errors.New("Database is corrupted!")
	//ErrorWTF is returned when an internal assertion fails - it shoudl not happen. Ever.
	ErrorWTF = errors.New("Something is seriously wrong. A internal assertion failed.")
)

//The DataRange which handles retrieving data from an Sql database
type sqlRange struct {
	r  *sql.Rows
	da *DatapointArray
}

//Clears all resources used by the sqlRange
func (s *sqlRange) Close() {
	if s.r != nil {
		s.r.Close()
		s.r = nil
	}
}

//A dummy function, it doesn't actually do anything.
//It exists just so that sqlRange fits the DataRange interface
func (s *sqlRange) Init() error {
	return nil
}

//Returns the next datapoint from the sqlRange
func (s *sqlRange) Next() (*Datapoint, error) {
	d, _ := s.da.Next() //Next on DatapointArray never returns error
	if d != nil {
		return d, nil
	}

	//The DatapointArray is now empty - check if the iterator is still functional
	if s.r == nil {
		return nil, nil
	}

	if !s.r.Next() { //Check if there is more data to read
		err := s.r.Err()
		s.Close()
		return nil, err
	}

	//There is more data to read!
	var endindex uint64 //We don't actually care about this in our case - but we need to scan it
	var data []byte
	if err := s.r.Scan(&endindex, &data); err != nil {
		s.Close()
		return nil, err
	}
	s.da = DatapointArrayFromBytes(data)
	//s.da = DatapointArrayFromCompressedBytes(data)

	//Repeat the procedure.
	return s.Next()
}

//The SqlStore stores and queries arrays of Datapoints in an SQL database. The table 'timebatchtable' is assumed
//to already exist and the correct indices are assumed to already exist.
type SqlStore struct {
	inserter   *sql.Stmt
	timequery  *sql.Stmt
	indexquery *sql.Stmt
	endindex   *sql.Stmt
	delkey     *sql.Stmt
	delprefix  *sql.Stmt
}

//Close all resources associated with the SqlStore.
func (s *SqlStore) Close() {
	s.inserter.Close()
	s.timequery.Close()
	s.indexquery.Close()
	s.endindex.Close()
	s.delkey.Close()
}

//GetEndIndex returns the first index point outside of the most recent datapointarray stored within the database.
//In effect, if the datapoints in a key were all in one huge array, returns array.length
//(not including the datapoints which are not yet committed to the SqlStore)
func (s *SqlStore) GetEndIndex(key string) (ei uint64, err error) {
	rows, err := s.endindex.Query(key)
	if err != nil {
		return 0, err
	}
	if !rows.Next() {
		return 0, ErrorWTF //This should never happen
	}
	err = rows.Scan(&ei)
	rows.Close()
	return ei, err
}

//Insert the given DatapointArray into the sql database given the startindex of the array for the key.
func (s *SqlStore) Insert(key string, startindex uint64, da *DatapointArray) error {
	_, err := s.inserter.Exec(key, da.Datapoints[da.Len()-1].Timestamp(),
		startindex+uint64(da.Len()), da.Bytes())
	//startindex+uint64(da.Len()),da.CompressedBytes())
	return err
}

//Append the given DatapointArray to the data stream for key
func (s *SqlStore) Append(key string, dp *DatapointArray) error {
	i, err := s.GetEndIndex(key)
	if err != nil {
		return err
	}
	return s.Insert(key, i, dp)
}

//Delete all data associated with the given key in the database
func (s *SqlStore) Delete(key string) error {
	_, err := s.delkey.Exec(key)
	return err
}

//DeletePrefix removes all data associated with the given prefix in the database. It allows to delete
//data which has keys ordered in a heirarchy.
func (s *SqlStore) DeletePrefix(prefix string) error {
	_, err := s.delprefix.Exec(prefix + "%")
	return err
}

//GetByTime returns a DataRange of datapoints starting at the starttime
func (s *SqlStore) GetByTime(key string, starttime int64) (dr DataRange, startindex uint64, err error) {
	rows, err := s.timequery.Query(key, starttime)
	if err != nil {
		return EmptyRange{}, 0, err
	}

	if !rows.Next() { //Check if there is any data to read
		startindex, err = s.GetEndIndex(key)
		if rows.Err() != nil {
			err = rows.Err()
		}
		return EmptyRange{}, startindex, rows.Err()
	}

	//There is some data!
	var endindex uint64
	var data []byte
	if err = rows.Scan(&endindex, &data); err != nil {
		return EmptyRange{}, endindex, err
	}

	da := DatapointArrayFromBytes(data).TStart(starttime)
	//da := DatapointArrayFromCompressedBytes(data).TStart(starttime)
	if da == nil || uint64(da.Len()) > endindex {
		rows.Close()
		return EmptyRange{}, endindex, ErrorDatabaseCorrupted
	}

	return &sqlRange{rows, da}, endindex - uint64(da.Len()), nil
}

//GetByIndex returns a DataRange of datapoints starting at the nearest dataindex to the given startindex
func (s *SqlStore) GetByIndex(key string, startindex uint64) (dr DataRange, dataindex uint64, err error) {
	rows, err := s.indexquery.Query(key, startindex)
	if err != nil {
		return EmptyRange{}, 0, err
	}

	if !rows.Next() { //Check if there is any data to read
		dataindex, err = s.GetEndIndex(key)
		if rows.Err() != nil {
			err = rows.Err()
		}
		return EmptyRange{}, dataindex, err
	}

	//There is some data!
	var endindex uint64
	var data []byte
	if err = rows.Scan(&endindex, &data); err != nil {
		return EmptyRange{}, endindex, err
	}
	da := DatapointArrayFromBytes(data)
	//da := DatapointArrayFromCompressedBytes(data)

	if da == nil || uint64(da.Len()) > endindex {
		rows.Close()
		return EmptyRange{}, endindex, ErrorDatabaseCorrupted
	}

	//Lastly, we start the DatapointArray from the correct index
	//This subtraction is guaranteed to work on uint, since query requires $gt
	fromend := endindex - startindex
	if fromend < uint64(da.Len()) {
		//The index we want is within the datarange
		da = NewDatapointArray(da.Datapoints[da.Len()-int(fromend):])
	}

	return &sqlRange{rows, da}, endindex - uint64(da.Len()), nil
}

//prepareSqlStore sets up the inserts (it assumes that the database was already prepared)
func prepareSqlStore(db *sql.DB, insertStatement, timequeryStatement, indexqueryStatement,
	endindexStatement, delkeyStatement, delprefixStatement string) (*SqlStore, error) {
	inserter, err := db.Prepare(insertStatement)
	if err != nil {
		return nil, err
	}

	timequery, err := db.Prepare(timequeryStatement)
	if err != nil {
		inserter.Close()
		return nil, err
	}

	indexquery, err := db.Prepare(indexqueryStatement)
	if err != nil {
		inserter.Close()
		timequery.Close()
		return nil, err
	}

	endindex, err := db.Prepare(endindexStatement)
	if err != nil {
		inserter.Close()
		timequery.Close()
		indexquery.Close()
		return nil, err
	}

	delkey, err := db.Prepare(delkeyStatement)
	if err != nil {
		inserter.Close()
		timequery.Close()
		indexquery.Close()
		endindex.Close()
		return nil, err
	}

	delprefix, err := db.Prepare(delprefixStatement)
	if err != nil {
		inserter.Close()
		timequery.Close()
		indexquery.Close()
		endindex.Close()
		delkey.Close()
		return nil, err
	}

	return &SqlStore{inserter, timequery, indexquery, endindex, delkey, delprefix}, nil
}

//OpenSQLiteStore initializes an sqlite database to work with an SqlStore.
func OpenSQLiteStore(db *sql.DB) (*SqlStore, error) {
	if err := db.Ping(); err != nil {
		return nil, err
	}
	tx, err := db.Begin()
	if err != nil {
		return nil, err
	}

	_, err = tx.Exec(`CREATE TABLE IF NOT EXISTS timebatchtable
        (
            Key STRING NOT NULL,
            EndTime INTEGER,
            EndIndex INTEGER,
            Data BLOB,
            PRIMARY KEY (Key, EndIndex)
            );`)
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	_, err = tx.Exec("CREATE INDEX IF NOT EXISTS KeyTime ON timebatchtable (Key,EndTime ASC)")
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	err = tx.Commit()
	if err != nil {
		return nil, err
	}

	//Now that tables are all set up, prepare the queries to run on the database

	return prepareSqlStore(db, "INSERT INTO timebatchtable VALUES (?,?,?,?);",
		"SELECT EndIndex,Data FROM timebatchtable WHERE Key=? AND EndTime > ? ORDER BY EndTime ASC",
		"SELECT EndIndex,Data FROM timebatchtable WHERE Key=? AND EndIndex > ? ORDER BY EndIndex ASC",
		"SELECT ifnull(max(EndIndex),0) FROM timebatchtable WHERE Key=?",
		"DELETE FROM timebatchtable WHERE Key=?",
		"DELETE FROM timebatchtable WHERE Key LIKE ?")
}

//OpenPostgresStore initializes a postgres database to work with an SqlStore.
func OpenPostgresStore(db *sql.DB) (*SqlStore, error) {
	if err := db.Ping(); err != nil {
		return nil, err
	}
	tx, err := db.Begin()
	if err != nil {
		return nil, err
	}

	_, err = tx.Exec(`CREATE TABLE IF NOT EXISTS timebatchtable
        (
            Key VARCHAR NOT NULL,
            EndTime BIGINT,
            EndIndex BIGINT,
            Data BYTEA,
            PRIMARY KEY (Key, EndIndex)
            );`)
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	//As of writing this code, postgres does not have CREATE INDEX IF NOT EXISTS, so we manually check it.
	//Based upon http://stackoverflow.com/questions/24674281/create-unique-index-if-not-exists-in-postgresql
	_, err = tx.Exec(`DO
        $$
        DECLARE
            l_count integer;
        BEGIN
            select count(*) into l_count from pg_indexes where schemaname = 'public'
                        and tablename = 'timebatchtable' and indexname = 'keytime';
            if l_count = 0 then
                CREATE INDEX keytime ON timebatchtable (Key,EndTime ASC);
            end if;
        END;
        $$`)
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	err = tx.Commit()
	if err != nil {
		return nil, err
	}

	//Now that tables are all set up, prepare the queries to run on the database
	return prepareSqlStore(db, "INSERT INTO timebatchtable VALUES ($1,$2,$3,$4);",
		"SELECT EndIndex,Data FROM timebatchtable WHERE Key=$1 AND EndTime > $2 ORDER BY EndTime ASC;",
		"SELECT EndIndex,Data FROM timebatchtable WHERE Key=$1 AND EndIndex > $2 ORDER BY EndIndex ASC;",
		"SELECT COALESCE(MAX(EndIndex),0) FROM timebatchtable WHERE Key=$1;",
		"DELETE FROM timebatchtable WHERE Key=$1;",
		"DELETE FROM timebatchtable WHERE Key LIKE $1;")
}

//OpenSqlStore uses the correct initializer for the given database driver. The err parameter allows daisychains of errors
func OpenSqlStore(db *sql.DB, sqldriver string, err error) (*SqlStore, error) {
	if err != nil {
		return nil, err
	}
	switch sqldriver {
	case "sqlite3":
		return OpenSQLiteStore(db)
	case "postgres":
		return OpenPostgresStore(db)
	}
	return nil, ErrorDatabaseDriver
}
<commit_msg>TimebatchDB: Reenabled compression of batches<commit_after>package timebatchdb

import (
	"database/sql"
	"errors"
)

var (
	//ErrorDatabaseDriver is called when the database driver given when initializing is unrecognized
	ErrorDatabaseDriver = errors.New("Database driver not supported")
	//ErrorDatabaseCorrupted is returned when there is data loss or inconsistency in the database
	ErrorDatabaseCorrupted = errors.New("Database is corrupted!")
	//ErrorWTF is returned when an internal assertion fails - it shoudl not happen. Ever.
	ErrorWTF = errors.New("Something is seriously wrong. A internal assertion failed.")
)

//The DataRange which handles retrieving data from an Sql database
type sqlRange struct {
	r  *sql.Rows
	da *DatapointArray
}

//Clears all resources used by the sqlRange
func (s *sqlRange) Close() {
	if s.r != nil {
		s.r.Close()
		s.r = nil
	}
}

//A dummy function, it doesn't actually do anything.
//It exists just so that sqlRange fits the DataRange interface
func (s *sqlRange) Init() error {
	return nil
}

//Returns the next datapoint from the sqlRange
func (s *sqlRange) Next() (*Datapoint, error) {
	d, _ := s.da.Next() //Next on DatapointArray never returns error
	if d != nil {
		return d, nil
	}

	//The DatapointArray is now empty - check if the iterator is still functional
	if s.r == nil {
		return nil, nil
	}

	if !s.r.Next() { //Check if there is more data to read
		err := s.r.Err()
		s.Close()
		return nil, err
	}

	//There is more data to read!
	var endindex uint64 //We don't actually care about this in our case - but we need to scan it
	var data []byte
	if err := s.r.Scan(&endindex, &data); err != nil {
		s.Close()
		return nil, err
	}
	//s.da = DatapointArrayFromBytes(data)
	s.da = DatapointArrayFromCompressedBytes(data)

	//Repeat the procedure.
	return s.Next()
}

//The SqlStore stores and queries arrays of Datapoints in an SQL database. The table 'timebatchtable' is assumed
//to already exist and the correct indices are assumed to already exist.
type SqlStore struct {
	inserter   *sql.Stmt
	timequery  *sql.Stmt
	indexquery *sql.Stmt
	endindex   *sql.Stmt
	delkey     *sql.Stmt
	delprefix  *sql.Stmt
}

//Close all resources associated with the SqlStore.
func (s *SqlStore) Close() {
	s.inserter.Close()
	s.timequery.Close()
	s.indexquery.Close()
	s.endindex.Close()
	s.delkey.Close()
}

//GetEndIndex returns the first index point outside of the most recent datapointarray stored within the database.
//In effect, if the datapoints in a key were all in one huge array, returns array.length
//(not including the datapoints which are not yet committed to the SqlStore)
func (s *SqlStore) GetEndIndex(key string) (ei uint64, err error) {
	rows, err := s.endindex.Query(key)
	if err != nil {
		return 0, err
	}
	if !rows.Next() {
		return 0, ErrorWTF //This should never happen
	}
	err = rows.Scan(&ei)
	rows.Close()
	return ei, err
}

//Insert the given DatapointArray into the sql database given the startindex of the array for the key.
func (s *SqlStore) Insert(key string, startindex uint64, da *DatapointArray) error {
	_, err := s.inserter.Exec(key, da.Datapoints[da.Len()-1].Timestamp(), startindex+uint64(da.Len()),
		//da.Bytes())
		da.CompressedBytes())
	return err
}

//Append the given DatapointArray to the data stream for key
func (s *SqlStore) Append(key string, dp *DatapointArray) error {
	i, err := s.GetEndIndex(key)
	if err != nil {
		return err
	}
	return s.Insert(key, i, dp)
}

//Delete all data associated with the given key in the database
func (s *SqlStore) Delete(key string) error {
	_, err := s.delkey.Exec(key)
	return err
}

//DeletePrefix removes all data associated with the given prefix in the database. It allows to delete
//data which has keys ordered in a heirarchy.
func (s *SqlStore) DeletePrefix(prefix string) error {
	_, err := s.delprefix.Exec(prefix + "%")
	return err
}

//GetByTime returns a DataRange of datapoints starting at the starttime
func (s *SqlStore) GetByTime(key string, starttime int64) (dr DataRange, startindex uint64, err error) {
	rows, err := s.timequery.Query(key, starttime)
	if err != nil {
		return EmptyRange{}, 0, err
	}

	if !rows.Next() { //Check if there is any data to read
		startindex, err = s.GetEndIndex(key)
		if rows.Err() != nil {
			err = rows.Err()
		}
		return EmptyRange{}, startindex, rows.Err()
	}

	//There is some data!
	var endindex uint64
	var data []byte
	if err = rows.Scan(&endindex, &data); err != nil {
		return EmptyRange{}, endindex, err
	}

	//da := DatapointArrayFromBytes(data).TStart(starttime)
	da := DatapointArrayFromCompressedBytes(data).TStart(starttime)
	if da == nil || uint64(da.Len()) > endindex {
		rows.Close()
		return EmptyRange{}, endindex, ErrorDatabaseCorrupted
	}

	return &sqlRange{rows, da}, endindex - uint64(da.Len()), nil
}

//GetByIndex returns a DataRange of datapoints starting at the nearest dataindex to the given startindex
func (s *SqlStore) GetByIndex(key string, startindex uint64) (dr DataRange, dataindex uint64, err error) {
	rows, err := s.indexquery.Query(key, startindex)
	if err != nil {
		return EmptyRange{}, 0, err
	}

	if !rows.Next() { //Check if there is any data to read
		dataindex, err = s.GetEndIndex(key)
		if rows.Err() != nil {
			err = rows.Err()
		}
		return EmptyRange{}, dataindex, err
	}

	//There is some data!
	var endindex uint64
	var data []byte
	if err = rows.Scan(&endindex, &data); err != nil {
		return EmptyRange{}, endindex, err
	}
	//da := DatapointArrayFromBytes(data)
	da := DatapointArrayFromCompressedBytes(data)

	if da == nil || uint64(da.Len()) > endindex {
		rows.Close()
		return EmptyRange{}, endindex, ErrorDatabaseCorrupted
	}

	//Lastly, we start the DatapointArray from the correct index
	//This subtraction is guaranteed to work on uint, since query requires $gt
	fromend := endindex - startindex
	if fromend < uint64(da.Len()) {
		//The index we want is within the datarange
		da = NewDatapointArray(da.Datapoints[da.Len()-int(fromend):])
	}

	return &sqlRange{rows, da}, endindex - uint64(da.Len()), nil
}

//prepareSqlStore sets up the inserts (it assumes that the database was already prepared)
func prepareSqlStore(db *sql.DB, insertStatement, timequeryStatement, indexqueryStatement,
	endindexStatement, delkeyStatement, delprefixStatement string) (*SqlStore, error) {
	inserter, err := db.Prepare(insertStatement)
	if err != nil {
		return nil, err
	}

	timequery, err := db.Prepare(timequeryStatement)
	if err != nil {
		inserter.Close()
		return nil, err
	}

	indexquery, err := db.Prepare(indexqueryStatement)
	if err != nil {
		inserter.Close()
		timequery.Close()
		return nil, err
	}

	endindex, err := db.Prepare(endindexStatement)
	if err != nil {
		inserter.Close()
		timequery.Close()
		indexquery.Close()
		return nil, err
	}

	delkey, err := db.Prepare(delkeyStatement)
	if err != nil {
		inserter.Close()
		timequery.Close()
		indexquery.Close()
		endindex.Close()
		return nil, err
	}

	delprefix, err := db.Prepare(delprefixStatement)
	if err != nil {
		inserter.Close()
		timequery.Close()
		indexquery.Close()
		endindex.Close()
		delkey.Close()
		return nil, err
	}

	return &SqlStore{inserter, timequery, indexquery, endindex, delkey, delprefix}, nil
}

//OpenSQLiteStore initializes an sqlite database to work with an SqlStore.
func OpenSQLiteStore(db *sql.DB) (*SqlStore, error) {
	if err := db.Ping(); err != nil {
		return nil, err
	}
	tx, err := db.Begin()
	if err != nil {
		return nil, err
	}

	_, err = tx.Exec(`CREATE TABLE IF NOT EXISTS timebatchtable
        (
            Key STRING NOT NULL,
            EndTime INTEGER,
            EndIndex INTEGER,
            Data BLOB,
            PRIMARY KEY (Key, EndIndex)
            );`)
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	_, err = tx.Exec("CREATE INDEX IF NOT EXISTS KeyTime ON timebatchtable (Key,EndTime ASC)")
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	err = tx.Commit()
	if err != nil {
		return nil, err
	}

	//Now that tables are all set up, prepare the queries to run on the database

	return prepareSqlStore(db, "INSERT INTO timebatchtable VALUES (?,?,?,?);",
		"SELECT EndIndex,Data FROM timebatchtable WHERE Key=? AND EndTime > ? ORDER BY EndTime ASC",
		"SELECT EndIndex,Data FROM timebatchtable WHERE Key=? AND EndIndex > ? ORDER BY EndIndex ASC",
		"SELECT ifnull(max(EndIndex),0) FROM timebatchtable WHERE Key=?",
		"DELETE FROM timebatchtable WHERE Key=?",
		"DELETE FROM timebatchtable WHERE Key LIKE ?")
}

//OpenPostgresStore initializes a postgres database to work with an SqlStore.
func OpenPostgresStore(db *sql.DB) (*SqlStore, error) {
	if err := db.Ping(); err != nil {
		return nil, err
	}
	tx, err := db.Begin()
	if err != nil {
		return nil, err
	}

	_, err = tx.Exec(`CREATE TABLE IF NOT EXISTS timebatchtable
        (
            Key VARCHAR NOT NULL,
            EndTime BIGINT,
            EndIndex BIGINT,
            Data BYTEA,
            PRIMARY KEY (Key, EndIndex)
            );`)
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	//As of writing this code, postgres does not have CREATE INDEX IF NOT EXISTS, so we manually check it.
	//Based upon http://stackoverflow.com/questions/24674281/create-unique-index-if-not-exists-in-postgresql
	_, err = tx.Exec(`DO
        $$
        DECLARE
            l_count integer;
        BEGIN
            select count(*) into l_count from pg_indexes where schemaname = 'public'
                        and tablename = 'timebatchtable' and indexname = 'keytime';
            if l_count = 0 then
                CREATE INDEX keytime ON timebatchtable (Key,EndTime ASC);
            end if;
        END;
        $$`)
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	err = tx.Commit()
	if err != nil {
		return nil, err
	}

	//Now that tables are all set up, prepare the queries to run on the database
	return prepareSqlStore(db, "INSERT INTO timebatchtable VALUES ($1,$2,$3,$4);",
		"SELECT EndIndex,Data FROM timebatchtable WHERE Key=$1 AND EndTime > $2 ORDER BY EndTime ASC;",
		"SELECT EndIndex,Data FROM timebatchtable WHERE Key=$1 AND EndIndex > $2 ORDER BY EndIndex ASC;",
		"SELECT COALESCE(MAX(EndIndex),0) FROM timebatchtable WHERE Key=$1;",
		"DELETE FROM timebatchtable WHERE Key=$1;",
		"DELETE FROM timebatchtable WHERE Key LIKE $1;")
}

//OpenSqlStore uses the correct initializer for the given database driver. The err parameter allows daisychains of errors
func OpenSqlStore(db *sql.DB, sqldriver string, err error) (*SqlStore, error) {
	if err != nil {
		return nil, err
	}
	switch sqldriver {
	case "sqlite3":
		return OpenSQLiteStore(db)
	case "postgres":
		return OpenPostgresStore(db)
	}
	return nil, ErrorDatabaseDriver
}
<|endoftext|>


<commit_before>package sarama

import (
	"log"
	"testing"
	"time"
)

var (
	broker, coordinator *mockBroker
	testClient          Client
	config              *Config
)

func initOM(t *testing.T) OffsetManager {
	config = NewConfig()
	config.Metadata.Retry.Max = 1
	config.Consumer.Offsets.CommitInterval = 1 * time.Millisecond

	broker = newMockBroker(t, 1)
	coordinator = newMockBroker(t, 2)

	seedMeta := new(MetadataResponse)
	seedMeta.AddBroker(coordinator.Addr(), coordinator.BrokerID())
	seedMeta.AddTopicPartition("my_topic", 0, 1, []int32{}, []int32{}, ErrNoError)
	seedMeta.AddTopicPartition("my_topic", 1, 1, []int32{}, []int32{}, ErrNoError)
	broker.Returns(seedMeta)

	var err error
	testClient, err = NewClient([]string{broker.Addr()}, config)
	if err != nil {
		t.Fatal(err)
	}

	broker.Returns(&ConsumerMetadataResponse{
		CoordinatorID:   coordinator.BrokerID(),
		CoordinatorHost: "127.0.0.1",
		CoordinatorPort: coordinator.Port(),
	})

	om, err := NewOffsetManagerFromClient("group", testClient)
	if err != nil {
		t.Fatal(err)
	}

	return om
}

func initPOM(t *testing.T) PartitionOffsetManager {
	om := initOM(t)

	fetchResponse := new(OffsetFetchResponse)
	fetchResponse.AddBlock("my_topic", 0, &OffsetFetchResponseBlock{
		Err:      ErrNoError,
		Offset:   5,
		Metadata: "test_meta",
	})
	coordinator.Returns(fetchResponse)

	pom, err := om.ManagePartition("my_topic", 0)
	if err != nil {
		t.Fatal(err)
	}
	return pom
}

func TestNewOffsetManager(t *testing.T) {
	seedBroker := newMockBroker(t, 1)
	seedBroker.Returns(new(MetadataResponse))

	testClient, err := NewClient([]string{seedBroker.Addr()}, nil)
	if err != nil {
		t.Fatal(err)
	}

	_, err = NewOffsetManagerFromClient("grouop", testClient)
	if err != nil {
		t.Error(err)
	}

	testClient.Close()

	_, err = NewOffsetManagerFromClient("group", testClient)
	if err != ErrClosedClient {
		t.Errorf("Error expected for closed client; actual value: %v", err)
	}

	seedBroker.Close()
}

// Test recovery from ErrNotCoordinatorForConsumer
// on first fetchInitialOffset call
func TestFetchInitialFail(t *testing.T) {
	om := initOM(t)

	// Error on first fetchInitialOffset call
	responseBlock := OffsetFetchResponseBlock{
		Err:      ErrNotCoordinatorForConsumer,
		Offset:   5,
		Metadata: "test_meta",
	}

	fetchResponse := new(OffsetFetchResponse)
	fetchResponse.AddBlock("my_topic", 0, &responseBlock)
	coordinator.Returns(fetchResponse)

	// Refresh coordinator
	newCoordinator := newMockBroker(t, 3)
	refreshResponse := new(ConsumerMetadataResponse)
	refreshResponse.CoordinatorID = newCoordinator.BrokerID()
	refreshResponse.CoordinatorHost = "127.0.0.1"
	refreshResponse.CoordinatorPort = newCoordinator.Port()
	broker.Returns(refreshResponse)

	// Second fetchInitialOffset call is fine
	fetchResponse2 := new(OffsetFetchResponse)
	responseBlock2 := responseBlock
	responseBlock2.Err = ErrNoError
	fetchResponse2.AddBlock("my_topic", 0, &responseBlock2)
	newCoordinator.Returns(fetchResponse2)

	if _, err := om.ManagePartition("my_topic", 0); err != nil {
		t.Error(err)
	}
}

// Test fetchInitialOffset retry on ErrOffsetsLoadInProgress
func TestFetchInitialInProgress(t *testing.T) {
	om := initOM(t)
	// Remove once fix is merged in
	config.Consumer.Offsets.CommitInterval = 10 * time.Second

	// Error on first fetchInitialOffset call
	responseBlock := OffsetFetchResponseBlock{
		Err:      ErrOffsetsLoadInProgress,
		Offset:   5,
		Metadata: "test_meta",
	}

	fetchResponse := new(OffsetFetchResponse)
	fetchResponse.AddBlock("my_topic", 0, &responseBlock)
	coordinator.Returns(fetchResponse)

	// Second fetchInitialOffset call is fine
	fetchResponse2 := new(OffsetFetchResponse)
	responseBlock2 := responseBlock
	responseBlock2.Err = ErrNoError
	fetchResponse2.AddBlock("my_topic", 0, &responseBlock2)
	coordinator.Returns(fetchResponse2)

	if _, err := om.ManagePartition("my_topic", 0); err != nil {
		t.Error(err)
	}

}

func TestOffset(t *testing.T) {
	pom := initPOM(t)
	offset, meta := pom.Offset()
	if offset != 5 {
		t.Errorf("Expected offset 5. Actual: %v", offset)
	}
	if meta != "test_meta" {
		t.Errorf("Expected metadata \"test_meta\". Actual: %q", meta)
	}

	pom.Close()
	testClient.Close()
	broker.Close()
	coordinator.Close()
}

func TestSetOffset(t *testing.T) {
	pom := initPOM(t)

	ocResponse := new(OffsetCommitResponse)
	ocResponse.AddError("my_topic", 0, ErrNoError)
	coordinator.Returns(ocResponse)

	pom.SetOffset(100, "modified_meta")
	offset, meta := pom.Offset()

	if offset != 100 {
		t.Errorf("Expected offset 100. Actual: %v", offset)
	}
	if meta != "modified_meta" {
		t.Errorf("Expected metadata \"modified_meta\". Actual: %q", meta)
	}

	pom.Close()
	testClient.Close()
	broker.Close()
	coordinator.Close()
}

func TestCommitErr(t *testing.T) {
	log.Println("TestCommitErr")
	log.Println("=============")
	pom := initPOM(t)

	ocResponse := new(OffsetCommitResponse)
	ocResponse.AddError("my_topic", 0, ErrOffsetOutOfRange)
	ocResponse.AddError("my_topic", 1, ErrNoError)
	coordinator.Returns(ocResponse)

	// ocResponse2 := new(OffsetCommitResponse)
	// // ocResponse.Errors
	// ocResponse2.AddError("my_topic", 1, ErrNoError)
	// coordinator.Returns(ocResponse2)

	freshCoordinator := newMockBroker(t, 3)

	// For RefreshCoordinator()
	coordinatorResponse3 := new(ConsumerMetadataResponse)
	coordinatorResponse3.CoordinatorID = freshCoordinator.BrokerID()
	coordinatorResponse3.CoordinatorHost = "127.0.0.1"
	coordinatorResponse3.CoordinatorPort = freshCoordinator.Port()
	broker.Returns(coordinatorResponse3)

	ocResponse2 := new(OffsetCommitResponse)
	// ocResponse.Errors
	// ocResponse2.AddError("my_topic", 0, ErrOffsetOutOfRange)
	ocResponse2.AddError("my_topic", 0, ErrNoError)
	freshCoordinator.Returns(ocResponse2)

	pom.SetOffset(100, "modified_meta")

	err := pom.Close()
	if err != nil {
		t.Error(err)
	}
}
<commit_msg>Test to covert abort process.<commit_after>package sarama

import (
	"log"
	"testing"
	"time"
)

var (
	broker, coordinator *mockBroker
	testClient          Client
	config              *Config
)

func initOM(t *testing.T) OffsetManager {
	config = NewConfig()
	config.Metadata.Retry.Max = 1
	config.Consumer.Offsets.CommitInterval = 1 * time.Millisecond

	broker = newMockBroker(t, 1)
	coordinator = newMockBroker(t, 2)

	seedMeta := new(MetadataResponse)
	seedMeta.AddBroker(coordinator.Addr(), coordinator.BrokerID())
	seedMeta.AddTopicPartition("my_topic", 0, 1, []int32{}, []int32{}, ErrNoError)
	seedMeta.AddTopicPartition("my_topic", 1, 1, []int32{}, []int32{}, ErrNoError)
	broker.Returns(seedMeta)

	var err error
	testClient, err = NewClient([]string{broker.Addr()}, config)
	if err != nil {
		t.Fatal(err)
	}

	broker.Returns(&ConsumerMetadataResponse{
		CoordinatorID:   coordinator.BrokerID(),
		CoordinatorHost: "127.0.0.1",
		CoordinatorPort: coordinator.Port(),
	})

	om, err := NewOffsetManagerFromClient("group", testClient)
	if err != nil {
		t.Fatal(err)
	}

	return om
}

func initPOM(t *testing.T) PartitionOffsetManager {
	om := initOM(t)

	fetchResponse := new(OffsetFetchResponse)
	fetchResponse.AddBlock("my_topic", 0, &OffsetFetchResponseBlock{
		Err:      ErrNoError,
		Offset:   5,
		Metadata: "test_meta",
	})
	coordinator.Returns(fetchResponse)

	pom, err := om.ManagePartition("my_topic", 0)
	if err != nil {
		t.Fatal(err)
	}
	return pom
}

func TestNewOffsetManager(t *testing.T) {
	seedBroker := newMockBroker(t, 1)
	seedBroker.Returns(new(MetadataResponse))

	testClient, err := NewClient([]string{seedBroker.Addr()}, nil)
	if err != nil {
		t.Fatal(err)
	}

	_, err = NewOffsetManagerFromClient("group", testClient)
	if err != nil {
		t.Error(err)
	}

	testClient.Close()

	_, err = NewOffsetManagerFromClient("group", testClient)
	if err != ErrClosedClient {
		t.Errorf("Error expected for closed client; actual value: %v", err)
	}

	seedBroker.Close()
}

// Test recovery from ErrNotCoordinatorForConsumer
// on first fetchInitialOffset call
func TestFetchInitialFail(t *testing.T) {
	om := initOM(t)

	// Error on first fetchInitialOffset call
	responseBlock := OffsetFetchResponseBlock{
		Err:      ErrNotCoordinatorForConsumer,
		Offset:   5,
		Metadata: "test_meta",
	}

	fetchResponse := new(OffsetFetchResponse)
	fetchResponse.AddBlock("my_topic", 0, &responseBlock)
	coordinator.Returns(fetchResponse)

	// Refresh coordinator
	newCoordinator := newMockBroker(t, 3)
	refreshResponse := new(ConsumerMetadataResponse)
	refreshResponse.CoordinatorID = newCoordinator.BrokerID()
	refreshResponse.CoordinatorHost = "127.0.0.1"
	refreshResponse.CoordinatorPort = newCoordinator.Port()
	broker.Returns(refreshResponse)

	// Second fetchInitialOffset call is fine
	fetchResponse2 := new(OffsetFetchResponse)
	responseBlock2 := responseBlock
	responseBlock2.Err = ErrNoError
	fetchResponse2.AddBlock("my_topic", 0, &responseBlock2)
	newCoordinator.Returns(fetchResponse2)

	if _, err := om.ManagePartition("my_topic", 0); err != nil {
		t.Error(err)
	}
}

// Test fetchInitialOffset retry on ErrOffsetsLoadInProgress
func TestFetchInitialInProgress(t *testing.T) {
	om := initOM(t)

	// Error on first fetchInitialOffset call
	responseBlock := OffsetFetchResponseBlock{
		Err:      ErrOffsetsLoadInProgress,
		Offset:   5,
		Metadata: "test_meta",
	}

	fetchResponse := new(OffsetFetchResponse)
	fetchResponse.AddBlock("my_topic", 0, &responseBlock)
	coordinator.Returns(fetchResponse)

	// Second fetchInitialOffset call is fine
	fetchResponse2 := new(OffsetFetchResponse)
	responseBlock2 := responseBlock
	responseBlock2.Err = ErrNoError
	fetchResponse2.AddBlock("my_topic", 0, &responseBlock2)
	coordinator.Returns(fetchResponse2)

	if _, err := om.ManagePartition("my_topic", 0); err != nil {
		t.Error(err)
	}

}

func TestOffset(t *testing.T) {
	pom := initPOM(t)
	offset, meta := pom.Offset()
	if offset != 5 {
		t.Errorf("Expected offset 5. Actual: %v", offset)
	}
	if meta != "test_meta" {
		t.Errorf("Expected metadata \"test_meta\". Actual: %q", meta)
	}

	pom.Close()
	testClient.Close()
	broker.Close()
	coordinator.Close()
}

func TestSetOffset(t *testing.T) {
	pom := initPOM(t)

	ocResponse := new(OffsetCommitResponse)
	ocResponse.AddError("my_topic", 0, ErrNoError)
	coordinator.Returns(ocResponse)

	pom.SetOffset(100, "modified_meta")
	offset, meta := pom.Offset()

	if offset != 100 {
		t.Errorf("Expected offset 100. Actual: %v", offset)
	}
	if meta != "modified_meta" {
		t.Errorf("Expected metadata \"modified_meta\". Actual: %q", meta)
	}

	pom.Close()
	testClient.Close()
	broker.Close()
	coordinator.Close()
}

func TestCommitErr(t *testing.T) {
	log.Println("TestCommitErr")
	log.Println("=============")
	pom := initPOM(t)

	ocResponse := new(OffsetCommitResponse)
	ocResponse.AddError("my_topic", 0, ErrOffsetOutOfRange)
	ocResponse.AddError("my_topic", 1, ErrNoError)
	coordinator.Returns(ocResponse)

	// ocResponse2 := new(OffsetCommitResponse)
	// // ocResponse.Errors
	// ocResponse2.AddError("my_topic", 1, ErrNoError)
	// coordinator.Returns(ocResponse2)

	freshCoordinator := newMockBroker(t, 3)

	// For RefreshCoordinator()
	coordinatorResponse3 := new(ConsumerMetadataResponse)
	coordinatorResponse3.CoordinatorID = freshCoordinator.BrokerID()
	coordinatorResponse3.CoordinatorHost = "127.0.0.1"
	coordinatorResponse3.CoordinatorPort = freshCoordinator.Port()
	broker.Returns(coordinatorResponse3)

	ocResponse2 := new(OffsetCommitResponse)
	// ocResponse.Errors
	// ocResponse2.AddError("my_topic", 0, ErrOffsetOutOfRange)
	ocResponse2.AddError("my_topic", 0, ErrNoError)
	freshCoordinator.Returns(ocResponse2)

	pom.SetOffset(100, "modified_meta")

	err := pom.Close()
	if err != nil {
		t.Error(err)
	}
}

// Test of recovery from abort
func TestBOMAbort(t *testing.T) {
	pom := initPOM(t)
	coordinator.Close()

	// Refresh coordinator
	newCoordinator := newMockBroker(t, 3)
	refreshResponse := new(ConsumerMetadataResponse)
	refreshResponse.CoordinatorID = newCoordinator.BrokerID()
	refreshResponse.CoordinatorHost = "127.0.0.1"
	refreshResponse.CoordinatorPort = newCoordinator.Port()
	broker.Returns(refreshResponse)

	ocResponse := new(OffsetCommitResponse)
	ocResponse.AddError("my_topic", 0, ErrNoError)
	newCoordinator.Returns(ocResponse)

	pom.SetOffset(100, "modified_meta")
	offset, meta := pom.Offset()

	if offset != 100 {
		t.Errorf("Expected offset 100. Actual: %v", offset)
	}
	if meta != "modified_meta" {
		t.Errorf("Expected metadata \"modified_meta\". Actual: %q", meta)
	}

	pom.Close()
	testClient.Close()
}
<|endoftext|>


<commit_before>package operations

import (
	"encoding/json"

	"github.com/omise/omise-go/internal"
)

// Example:
//
//	customers, list := &omise.CustomerList{}, &ListCustomers{
//		List{
//			From: time.Now().Add(-1 * time.Hour),
//			Limit: 100
//		},
//	}
//	if e := client.Do(customers, list); e != nil {
//		panic(e)
//	}
//
//	fmt.Println("# of new customers in the last hour:", len(customers.Data))
//
type ListCustomers struct {
	List
}

func (req *ListCustomers) Describe() *internal.Description {
	return &internal.Description{
		Endpoint: internal.API,
		Method:   "GET",
		Path:     "/customers",
	}
}

// Example:
//
//	customer, create := &omise.Customer{}, &CreateCustomer{
//		Email:       "kokyaku@omise.co",
//		Description: "I'm a customer",
//		Card:        token.ID,
//	})
//	if e := client.Do(customer, create); e != nil {
//		panic(e)
//	}
//
//	fmt.Printf("created customer: %#v\n", customer)
//
type CreateCustomer struct {
	Email       string `json:"email,omitempty"`
	Description string `json:"description,omitempty"`
	Card        string `json:"card,omitempty"`
}

func (req *CreateCustomer) Describe() *internal.Description {
	return &internal.Description{
		Endpoint:    internal.API,
		Method:      "POST",
		Path:        "/customers",
		ContentType: "application/json",
	}
}

// Example:
//
//	cust, retrieve := &omise.Customer{}, &RetrieveCustomer{"cust_123"}
//	if e := client.Do(cust, retrieve); e != nil {
//		panic(e)
//	}
//
//	fmt.Printf("cust_123: %#v\n", cust)
//
type RetrieveCustomer struct {
	CustomerID string `json:"-"`
}

func (req *RetrieveCustomer) Describe() *internal.Description {
	return &internal.Description{
		Endpoint:    internal.API,
		Method:      "GET",
		Path:        "/customers/" + req.CustomerID,
		ContentType: "application/json",
	}
}

// Example:
//
//	cust, update := &&omise.Customer{}, UpdateCustomer{
//		CustomerID:  "cust_987",
//		Description: "I'm JOHN now.",
//	}
//	if e := client.Do(cust, update); e != nil {
//		panic(e)
//	}
//
//	fmt.Printf("updated customer: %#v\n", cust)
//
type UpdateCustomer struct {
	CustomerID  string `json:"-"`
	Email       string `json:"email,omitempty"`
	Description string `json:"description,omitempty"`
	Card        string `json:"card,omitempty"`
	DefaultCard string `json:"default_card,omitempty"`
}

func (req *UpdateCustomer) Describe() *internal.Description {
	return &internal.Description{
		Endpoint:    internal.API,
		Method:      "PATCH",
		Path:        "/customers/" + req.CustomerID,
		ContentType: "application/json",
	}
}

// Example:
//
//	del, destroy := &omise.Deletion{}, &DestroyCustomer{
//		CustomerID: "cust_123",
//	}
//	if e := client.Do(del, destroy); e != nil {
//		panic(e)
//	}
//
//	fmt.Println("destroyed customer:", del.ID)
//
type DestroyCustomer struct {
	CustomerID string `json:"-"`
}

func (req *DestroyCustomer) Describe() *internal.Description {
	return &internal.Description{
		Endpoint:    internal.API,
		Method:      "DELETE",
		Path:        "/customers/" + req.CustomerID,
		ContentType: "application/json",
	}
}

// ListCustomerChargeSchedules represent list customer schedule schedules API payload
//
// Example:
//
//      var schds omise.ScheduleList
//	list := ListCustomerChargeSchedules{
//		CustomerID: "cust_123"
//		List: List{
//			Limit: 100,
//			From: time.Now().Add(-1 * time.Hour),
//		},
//	}
//	if e := client.Do(&schds, &list); e != nil {
//		panic(e)
//	}
//
//	fmt.Println("# of schedules made in the last hour:", len(schds.Data))
//
type ListCustomerChargeSchedules struct {
	CustomerID string
	List
}

func (req *ListCustomerChargeSchedules) MarshalJSON() ([]byte, error) {
	return json.Marshal(req.List)
}

func (req *ListCustomerChargeSchedules) Describe() *internal.Description {
	return &internal.Description{
		Endpoint:    internal.API,
		Method:      "GET",
		Path:        "/customers/" + req.CustomerID + "/schedules",
		ContentType: "application/json",
	}
}
<commit_msg>Remove MarshalJSON from ListCustomerChargeSchedules<commit_after>package operations

import (
	"github.com/omise/omise-go/internal"
)

// Example:
//
//	customers, list := &omise.CustomerList{}, &ListCustomers{
//		List{
//			From: time.Now().Add(-1 * time.Hour),
//			Limit: 100
//		},
//	}
//	if e := client.Do(customers, list); e != nil {
//		panic(e)
//	}
//
//	fmt.Println("# of new customers in the last hour:", len(customers.Data))
//
type ListCustomers struct {
	List
}

func (req *ListCustomers) Describe() *internal.Description {
	return &internal.Description{
		Endpoint: internal.API,
		Method:   "GET",
		Path:     "/customers",
	}
}

// Example:
//
//	customer, create := &omise.Customer{}, &CreateCustomer{
//		Email:       "kokyaku@omise.co",
//		Description: "I'm a customer",
//		Card:        token.ID,
//	})
//	if e := client.Do(customer, create); e != nil {
//		panic(e)
//	}
//
//	fmt.Printf("created customer: %#v\n", customer)
//
type CreateCustomer struct {
	Email       string `json:"email,omitempty"`
	Description string `json:"description,omitempty"`
	Card        string `json:"card,omitempty"`
}

func (req *CreateCustomer) Describe() *internal.Description {
	return &internal.Description{
		Endpoint:    internal.API,
		Method:      "POST",
		Path:        "/customers",
		ContentType: "application/json",
	}
}

// Example:
//
//	cust, retrieve := &omise.Customer{}, &RetrieveCustomer{"cust_123"}
//	if e := client.Do(cust, retrieve); e != nil {
//		panic(e)
//	}
//
//	fmt.Printf("cust_123: %#v\n", cust)
//
type RetrieveCustomer struct {
	CustomerID string `json:"-"`
}

func (req *RetrieveCustomer) Describe() *internal.Description {
	return &internal.Description{
		Endpoint:    internal.API,
		Method:      "GET",
		Path:        "/customers/" + req.CustomerID,
		ContentType: "application/json",
	}
}

// Example:
//
//	cust, update := &&omise.Customer{}, UpdateCustomer{
//		CustomerID:  "cust_987",
//		Description: "I'm JOHN now.",
//	}
//	if e := client.Do(cust, update); e != nil {
//		panic(e)
//	}
//
//	fmt.Printf("updated customer: %#v\n", cust)
//
type UpdateCustomer struct {
	CustomerID  string `json:"-"`
	Email       string `json:"email,omitempty"`
	Description string `json:"description,omitempty"`
	Card        string `json:"card,omitempty"`
	DefaultCard string `json:"default_card,omitempty"`
}

func (req *UpdateCustomer) Describe() *internal.Description {
	return &internal.Description{
		Endpoint:    internal.API,
		Method:      "PATCH",
		Path:        "/customers/" + req.CustomerID,
		ContentType: "application/json",
	}
}

// Example:
//
//	del, destroy := &omise.Deletion{}, &DestroyCustomer{
//		CustomerID: "cust_123",
//	}
//	if e := client.Do(del, destroy); e != nil {
//		panic(e)
//	}
//
//	fmt.Println("destroyed customer:", del.ID)
//
type DestroyCustomer struct {
	CustomerID string `json:"-"`
}

func (req *DestroyCustomer) Describe() *internal.Description {
	return &internal.Description{
		Endpoint:    internal.API,
		Method:      "DELETE",
		Path:        "/customers/" + req.CustomerID,
		ContentType: "application/json",
	}
}

// ListCustomerChargeSchedules represent list customer schedule schedules API payload
//
// Example:
//
//      var schds omise.ScheduleList
//	list := ListCustomerChargeSchedules{
//		CustomerID: "cust_123"
//		List: List{
//			Limit: 100,
//			From: time.Now().Add(-1 * time.Hour),
//		},
//	}
//	if e := client.Do(&schds, &list); e != nil {
//		panic(e)
//	}
//
//	fmt.Println("# of schedules made in the last hour:", len(schds.Data))
//
type ListCustomerChargeSchedules struct {
	CustomerID string
	List
}

func (req *ListCustomerChargeSchedules) Describe() *internal.Description {
	return &internal.Description{
		Endpoint:    internal.API,
		Method:      "GET",
		Path:        "/customers/" + req.CustomerID + "/schedules",
		ContentType: "application/json",
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 Hajime Hoshi
//
// 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 graphics

import (
	"image/color"

	"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
)

func orthoProjectionMatrix(left, right, bottom, top int) *[4][4]float64 {
	e11 := float64(2) / float64(right-left)
	e22 := float64(2) / float64(top-bottom)
	e14 := -1 * float64(right+left) / float64(right-left)
	e24 := -1 * float64(top+bottom) / float64(top-bottom)

	return &[4][4]float64{
		{e11, 0, 0, e14},
		{0, e22, 0, e24},
		{0, 0, 1, 0},
		{0, 0, 0, 1},
	}
}

type Framebuffer struct {
	native    opengl.Framebuffer
	width     int
	height    int
	flipY     bool
	proMatrix *[4][4]float64
}

func NewZeroFramebuffer(c *opengl.Context, width, height int) (*Framebuffer, error) {
	r := &Framebuffer{
		width:  width,
		height: height,
		flipY:  true,
	}
	return r, nil
}

func NewFramebufferFromTexture(c *opengl.Context, texture *Texture) (*Framebuffer, error) {
	f, err := c.NewFramebuffer(opengl.Texture(texture.native))
	if err != nil {
		return nil, err
	}
	w, h := texture.Size()
	return &Framebuffer{
		native: f,
		width:  w,
		height: h,
	}, nil
}

func (f *Framebuffer) Size() (width, height int) {
	return f.width, f.height
}

func (f *Framebuffer) Dispose(c *opengl.Context) error {
	// Don't delete the default framebuffer.
	if f.native == opengl.ZeroFramebuffer {
		return nil
	}
	c.DeleteFramebuffer(f.native)
	return nil
}

func (f *Framebuffer) setAsViewport(c *opengl.Context) error {
	width := int(NextPowerOf2Int32(int32(f.width)))
	height := int(NextPowerOf2Int32(int32(f.height)))
	return c.SetViewport(f.native, width, height)
}

func (f *Framebuffer) projectionMatrix() *[4][4]float64 {
	if f.proMatrix != nil {
		return f.proMatrix
	}
	width := int(NextPowerOf2Int32(int32(f.width)))
	height := int(NextPowerOf2Int32(int32(f.height)))
	m := orthoProjectionMatrix(0, width, 0, height)
	if f.flipY {
		m[1][1] *= -1
		m[1][3] += float64(f.height) / float64(NextPowerOf2Int32(int32(f.height))) * 2
	}
	f.proMatrix = m
	return f.proMatrix
}

func (f *Framebuffer) Fill(context *opengl.Context, clr color.Color) error {
	c := &fillCommand{
		dst:   f,
		color: clr,
	}
	return c.Exec(context)
}

func (f *Framebuffer) DrawTexture(context *opengl.Context, t *Texture, vertices []int16, geo, clr Matrix, mode opengl.CompositeMode) error {
	c := &drawImageCommand{
		dst:      f,
		src:      t,
		vertices: vertices,
		geo:      geo,
		color:    clr,
		mode:     mode,
	}
	return c.Exec(context)
}

func (f *Framebuffer) Pixels(c *opengl.Context) ([]uint8, error) {
	w, h := f.Size()
	return c.FramebufferPixels(f.native, w, h)
}

func (f *Framebuffer) ReplacePixels(context *opengl.Context, t *Texture, p []uint8) error {
	c := &replacePixelsCommand{
		dst:     f,
		texture: t,
		pixels:  p,
	}
	return c.Exec(context)
}
<commit_msg>graphics: Remove Framebuffer.Size<commit_after>// Copyright 2014 Hajime Hoshi
//
// 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 graphics

import (
	"image/color"

	"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
)

func orthoProjectionMatrix(left, right, bottom, top int) *[4][4]float64 {
	e11 := float64(2) / float64(right-left)
	e22 := float64(2) / float64(top-bottom)
	e14 := -1 * float64(right+left) / float64(right-left)
	e24 := -1 * float64(top+bottom) / float64(top-bottom)

	return &[4][4]float64{
		{e11, 0, 0, e14},
		{0, e22, 0, e24},
		{0, 0, 1, 0},
		{0, 0, 0, 1},
	}
}

type Framebuffer struct {
	native    opengl.Framebuffer
	width     int
	height    int
	flipY     bool
	proMatrix *[4][4]float64
}

func NewZeroFramebuffer(c *opengl.Context, width, height int) (*Framebuffer, error) {
	r := &Framebuffer{
		width:  width,
		height: height,
		flipY:  true,
	}
	return r, nil
}

func NewFramebufferFromTexture(c *opengl.Context, texture *Texture) (*Framebuffer, error) {
	f, err := c.NewFramebuffer(opengl.Texture(texture.native))
	if err != nil {
		return nil, err
	}
	w, h := texture.Size()
	return &Framebuffer{
		native: f,
		width:  w,
		height: h,
	}, nil
}

func (f *Framebuffer) Dispose(c *opengl.Context) error {
	// Don't delete the default framebuffer.
	if f.native == opengl.ZeroFramebuffer {
		return nil
	}
	c.DeleteFramebuffer(f.native)
	return nil
}

func (f *Framebuffer) setAsViewport(c *opengl.Context) error {
	width := int(NextPowerOf2Int32(int32(f.width)))
	height := int(NextPowerOf2Int32(int32(f.height)))
	return c.SetViewport(f.native, width, height)
}

func (f *Framebuffer) projectionMatrix() *[4][4]float64 {
	if f.proMatrix != nil {
		return f.proMatrix
	}
	width := int(NextPowerOf2Int32(int32(f.width)))
	height := int(NextPowerOf2Int32(int32(f.height)))
	m := orthoProjectionMatrix(0, width, 0, height)
	if f.flipY {
		m[1][1] *= -1
		m[1][3] += float64(f.height) / float64(NextPowerOf2Int32(int32(f.height))) * 2
	}
	f.proMatrix = m
	return f.proMatrix
}

func (f *Framebuffer) Fill(context *opengl.Context, clr color.Color) error {
	c := &fillCommand{
		dst:   f,
		color: clr,
	}
	return c.Exec(context)
}

func (f *Framebuffer) DrawTexture(context *opengl.Context, t *Texture, vertices []int16, geo, clr Matrix, mode opengl.CompositeMode) error {
	c := &drawImageCommand{
		dst:      f,
		src:      t,
		vertices: vertices,
		geo:      geo,
		color:    clr,
		mode:     mode,
	}
	return c.Exec(context)
}

func (f *Framebuffer) Pixels(c *opengl.Context) ([]uint8, error) {
	return c.FramebufferPixels(f.native, f.width, f.height)
}

func (f *Framebuffer) ReplacePixels(context *opengl.Context, t *Texture, p []uint8) error {
	c := &replacePixelsCommand{
		dst:     f,
		texture: t,
		pixels:  p,
	}
	return c.Exec(context)
}
<|endoftext|>