<commit_before>package modl

import (
	"database/sql"

	"github.com/jmoiron/sqlx"
)

// Transaction represents a database transaction.
// Insert/Update/Delete/Get/Exec operations will be run in the context
// of that transaction.  Transactions should be terminated with
// a call to Commit() or Rollback()
type Transaction struct {
	dbmap *DbMap
	tx    *sqlx.Tx
}

// Insert has the same behavior as DbMap.Insert(), but runs in a transaction.
func (t *Transaction) Insert(list ...interface{}) error {
	return insert(t.dbmap, t, list...)
}

// Update has the same behavior as DbMap.Update(), but runs in a transaction.
func (t *Transaction) Update(list ...interface{}) (int64, error) {
	return update(t.dbmap, t, list...)
}

// Delete has the same behavior as DbMap.Delete(), but runs in a transaction.
func (t *Transaction) Delete(list ...interface{}) (int64, error) {
	return deletes(t.dbmap, t, list...)
}

// Get has the Same behavior as DbMap.Get(), but runs in a transaction.
func (t *Transaction) Get(dest interface{}, keys ...interface{}) error {
	return get(t.dbmap, t, dest, keys...)
}

// Select has the Same behavior as DbMap.Select(), but runs in a transaction.
func (t *Transaction) Select(dest interface{}, query string, args ...interface{}) error {
	return hookedselect(t.dbmap, t, dest, query, args...)
}

func (t *Transaction) SelectOne(dest interface{}, query string, args ...interface{}) error {
	return hookedget(t.dbmap, t, dest, query, args...)
}

// Exec has the same behavior as DbMap.Exec(), but runs in a transaction.
func (t *Transaction) Exec(query string, args ...interface{}) (sql.Result, error) {
	t.dbmap.trace(query, args)
	return t.tx.Exec(query, args...)
}

// Commit commits the underlying database transaction.
func (t *Transaction) Commit() error {
	t.dbmap.trace("commit;")
	return t.tx.Commit()
}

// Rollback rolls back the underlying database transaction.
func (t *Transaction) Rollback() error {
	t.dbmap.trace("rollback;")
	return t.tx.Rollback()
}

func (t *Transaction) handle() handle {
	return &tracingHandle{h: t.tx, d: t.dbmap}
}
<commit_msg>export Tx<commit_after>package modl

import (
	"database/sql"

	"github.com/jmoiron/sqlx"
)

// Transaction represents a database transaction.
// Insert/Update/Delete/Get/Exec operations will be run in the context
// of that transaction.  Transactions should be terminated with
// a call to Commit() or Rollback()
type Transaction struct {
	dbmap *DbMap
	Tx    *sqlx.Tx
}

// Insert has the same behavior as DbMap.Insert(), but runs in a transaction.
func (t *Transaction) Insert(list ...interface{}) error {
	return insert(t.dbmap, t, list...)
}

// Update has the same behavior as DbMap.Update(), but runs in a transaction.
func (t *Transaction) Update(list ...interface{}) (int64, error) {
	return update(t.dbmap, t, list...)
}

// Delete has the same behavior as DbMap.Delete(), but runs in a transaction.
func (t *Transaction) Delete(list ...interface{}) (int64, error) {
	return deletes(t.dbmap, t, list...)
}

// Get has the Same behavior as DbMap.Get(), but runs in a transaction.
func (t *Transaction) Get(dest interface{}, keys ...interface{}) error {
	return get(t.dbmap, t, dest, keys...)
}

// Select has the Same behavior as DbMap.Select(), but runs in a transaction.
func (t *Transaction) Select(dest interface{}, query string, args ...interface{}) error {
	return hookedselect(t.dbmap, t, dest, query, args...)
}

func (t *Transaction) SelectOne(dest interface{}, query string, args ...interface{}) error {
	return hookedget(t.dbmap, t, dest, query, args...)
}

// Exec has the same behavior as DbMap.Exec(), but runs in a transaction.
func (t *Transaction) Exec(query string, args ...interface{}) (sql.Result, error) {
	t.dbmap.trace(query, args)
	return t.Tx.Exec(query, args...)
}

// Commit commits the underlying database transaction.
func (t *Transaction) Commit() error {
	t.dbmap.trace("commit;")
	return t.Tx.Commit()
}

// Rollback rolls back the underlying database transaction.
func (t *Transaction) Rollback() error {
	t.dbmap.trace("rollback;")
	return t.Tx.Rollback()
}

func (t *Transaction) handle() handle {
	return &tracingHandle{h: t.Tx, d: t.dbmap}
}
<|endoftext|>


<commit_before>package gosaca

// recursive version of ComputeSuffixArray for levels 1+
func computeSuffixArray1(S, SA []int, k int) {
	n := len(S)

	// bit-invert any S-type characters in S
	// TODO - can our caller do this for us as he builds S?
	for i := n - 2; i >= 0; i-- {
		if (S[i+1] < 0 && S[i] <= ^S[i+1]) || // S[i+1] is S-type and we're <= it
			(S[i+1] >= 0 && S[i] < S[i+1]) { // S[i+1] is L-type and we're strictly < it
			S[i] = ^S[i]
		}
	}

	// *********************************************
	// Stage 1: Induced-sort the LMS-substrings of S
	// *********************************************

	// step 1 - initialize SA as empty
	setAllToEmpty(SA)

	// step 2 - put all LMS substrings into buckets based on their first character
	for i := n - 2; i >= 0; i-- {
		if S[i] >= 0 {
			// S[i] is L-type
			continue
		}
		// S[i] is S-type; walk back until S[i-1] is L-type or -1
		for i >= 1 && S[i-1] < 0 {
			// S[i-1] is also S-type
			i--
		}

		if i > 0 {
			// found LMS starting at S[i] - need to insert it into end of its bucket
			// by Property 4.1, S[i] holds pointer to the end of the bucket,
			// but we need to walk backwards if we've already put other LMS suffixes into the same bucket
			end := ^S[i]
			for SA[end] != empty {
				end--
			}
			SA[end] = i
		}
	}

	// step 3 - induced sort the L-type suffixes of S into their buckets
	induceSortL1(S, SA)

	// step 4 - induced sort the S-type suffixes of S into their buckets
	induceSortS1(S, SA)

	// compact all the now-sorted LMS substrings into the first n1 positions of SA
	n1 := 0
	for i := 0; i < n; i++ {
		if SA[i] > 0 && // S[0] is not LMS by definition
			S[SA[i]] < 0 && // S[SA[i]] is S-type
			S[SA[i]-1] >= 0 { // S[SA[i-1]] is L-type
			// S[i] is LMS
			SA[n1] = SA[i]
			n1++
		}
	}

	// *********************************************
	// Stage 2: Rename the LMS substrings
	// *********************************************

	// provably, n1 is at most floor(n/2), so the following overlapping works
	SA1 := SA[:n1] // SA1 overlaps the front of SA
	work := SA[n1:] // workspace overlaps the rest of SA
	S1 := SA[n-n1:] // S1 overlaps the end of SA (including part of "work", but rename deals with that correctly)
	k1 := rename1(S, SA1, work, S1)

	// *********************************************
	// Stage 3: Sort recursively
	// *********************************************
	if k1 == n1 {
		for i := 0; i < n1; i++ {
			SA1[S1[i]] = i
		}
	} else {
		computeSuffixArray1(S1, SA1, k1)
	}

	// NOT DESCRIBED IN PAPER BUT STILL NECESSARY (see SA-IS)
	// We need to undo the renaming of the LMS suffixes.
	// We no longer need S1, so reuse it to hold all the LMS indices.
	j := n1 - 1
	for i := n - 2; i >= 0; i-- {
		if S[i] >= 0 {
			// L-type; ignore
			continue
		}
		// S[i] is S-type; walk backwards to find LMS
		for i >= 1 && S[i-1] < 0 {
			// S[i-1] is also S-type; keep moving back
			i--
		}
		// S[0] is not LMS by definition, but otherwise S[i] is LMS
		if i > 0 {
			S1[j] = i
			j--
		}
	}
	// Now convert SA1 from renamed values to true values.
	for i := 0; i < n1; i++ {
		SA1[i] = S1[SA1[i]]
	}

	// *********************************************
	// Stage 4: Induced-sort SA(S) from SA1(S1)
	// *********************************************

	// step 1 - initialize SA[n1:] as empty
	setAllToEmpty(SA[n1:])

	// step 2 - put all the sorted LMS suffixes of S into their buckets in SA
	for i := n1 - 1; i >= 0; i-- {
		j := SA[i]
		SA[i] = empty
		c := ^S[j]
		if j == 0 {
			panic("unexpected j == 0")
		}
		// look backwards until we find an empty slot in the bucket
		for SA[c] != empty {
			c--
		}
		SA[c] = j
	}

	// step 3 - induced sort the L-type suffixes of S into their buckets
	induceSortL1(S, SA)

	// step 4 - induced sort the S-type suffixes of S into their buckets
	induceSortS1(S, SA)
}

// TODO pre-post
func induceSortL1(S, SA []int) {
	n := len(S)

	// special case to deal with the (virtual) sentinel:
	// S[n-1] is L-type because of the sentinel, and if we were treating
	// the sentinel as a real character, it would be at the front of SA[]
	// (it's effectively stored in "SA[-1]").
	//
	// Because c is L-type, we know SA[c] is empty, so we're in case 1 of section 4.1
	c := S[n-1]
	if c+1 < n && SA[c+1] == empty {
		SA[c+1] = n - 1
		SA[c] = -1
	} else {
		SA[c] = n - 1
	}

	for i := 0; i < n; i++ {
		if SA[i] < 0 {
			// SA[i] is empty or being used as a counter; nothing to do
			continue
		}
		j := SA[i] - 1
		// if we just grabbed the character before an LMS suffix, we need to clear
		// out that LMS suffix (induceSortS1 assumes only L-type suffixes are in SA)
		if S[SA[i]] < 0 {
			SA[i] = empty
		}
		if j < 0 {
			// SA[i] was == 0; there is no preceding character to look at
			continue
		}
		c := S[j]
		if c < 0 {
			// S[j] is S-type; move on
			continue
		}

		switch {
		case SA[c] >= 0:
			// section 4.1 case 2
			// left shift the previous bucket until we find the head
			// NOT MENTIONED IN PAPER: if we overwrite SA[i], we need
			// to *stay here* for the next iteration
			val := SA[c]
			overwroteSAi := (c == i)
			// TODO clean this up
			stop := false
			for x := c - 1; x >= 0 && !stop; x-- {
				prev := val
				val = SA[x]
				if val < 0 && val != empty {
					stop = true
				}
				SA[x] = prev
				if x == i {
					overwroteSAi = true
				}
			}
			if overwroteSAi {
				// decrement i; it will be incremented by the for loop, forcing us to look at SA[i] again next time
				i--
			}
			fallthrough // we now know SA[c] is empty so fall through

		case SA[c] == empty:
			// section 4.1 case 1
			if c+1 < n && SA[c+1] == empty {
				SA[c+1] = j
				SA[c] = -1
			} else {
				SA[c] = j
			}
			break

		default:
			// section 4.1 case 3 (SA[c] is a counter)
			d := SA[c]
			pos := c - d + 1
			if pos < n && SA[pos] == empty {
				SA[pos] = j
				SA[c]--
			} else {
				// left-shift SA[c+1:pos-1], inserting j into SA[pos-1]
				prev := j
				overwroteSAi := (c == i)
				for x := pos - 1; x >= c; x-- {
					val := SA[x]
					SA[x] = prev
					prev = val
					if x == i {
						overwroteSAi = true
					}
				}
				if overwroteSAi {
					i--
				}
			}
			break
		}
	}

	// NOT MENTIONED IN PAPER: We need to go back over SA and fix
	// any leftover counter values via left shifting the buckets appropriately.
	for i := 0; i < n; i++ {
		if SA[i] == empty || SA[i] >= 0 {
			continue
		}
		d := SA[i]
		pos := i - d + 1
		prev := empty
		for x := pos - 1; x >= i; x-- {
			val := SA[x]
			SA[x] = prev
			prev = val
		}
	}
}

// TODO pre-post
func induceSortS1(S, SA []int) {
	n := len(S)

	for i := n - 1; i >= 0; i-- {
		if SA[i] <= 0 {
			// SA[i] is empty or being used as a counter; nothing to do
			continue
		}
		j := SA[i] - 1
		c := ^S[j]
		if c < 0 {
			// S[j]==c is L-type; move on
			continue
		}

		switch {
		case SA[c] >= 0:
			// section 4.2 case 2
			val := SA[c]
			overwroteSAi := (c == i)
			stop := false
			for x := c + 1; x < n && !stop; x++ {
				prev := val
				val = SA[x]
				if val < 0 && val != empty {
					stop = true
				}
				SA[x] = prev
				if x == i {
					overwroteSAi = true
				}
			}
			if overwroteSAi {
				i++
			}
			fallthrough

		case SA[c] == empty:
			// section 4.2 case 1
			if c-1 >= 0 && SA[c-1] == empty {
				SA[c-1] = j
				SA[c] = -1
			} else {
				SA[c] = j
			}
			break

		default:
			// section 4.2 case 3
			d := SA[c]
			pos := c + d - 1
			if pos >= 0 && SA[pos] == empty {
				SA[pos] = j
				SA[c]--
			} else {
				// right-shift SA[pos+1:c-1], inserting j into SA[pos+1]
				prev := j
				overwroteSAi := (c == i) // TODO - can default to false?
				for x := pos + 1; x <= c; x++ {
					val := SA[x]
					SA[x] = prev
					prev = val
					if x == i {
						overwroteSAi = true
					}
				}
				if overwroteSAi {
					i++
				}
			}
			break
		}
	}
	// TODO PICKUP AT LINE 320
}
<commit_msg>Replace O(n^2) lookback loop in recursive calls.<commit_after>package gosaca

// recursive version of ComputeSuffixArray for levels 1+
func computeSuffixArray1(S, SA []int, k int) {
	n := len(S)

	// bit-invert any S-type characters in S
	// TODO - can our caller do this for us as he builds S?
	for i := n - 2; i >= 0; i-- {
		if (S[i+1] < 0 && S[i] <= ^S[i+1]) || // S[i+1] is S-type and we're <= it
			(S[i+1] >= 0 && S[i] < S[i+1]) { // S[i+1] is L-type and we're strictly < it
			S[i] = ^S[i]
		}
	}

	// *********************************************
	// Stage 1: Induced-sort the LMS-substrings of S
	// *********************************************

	// step 1 - initialize SA as empty
	setAllToEmpty(SA)

	// step 2 - put all LMS substrings into buckets based on their first character
	for i := n - 2; i >= 0; i-- {
		if S[i] >= 0 {
			// S[i] is L-type
			continue
		}

		// S[i] is S-type; walk back until S[i-1] is L-type or -1
		for i >= 1 && S[i-1] < 0 {
			// S[i-1] is also S-type
			i--
		}

		if i == 0 {
			// even if S[0] is S-type, it's not LMS - we're done
			break
		}

		// We might need to put multiple LMS substrings into the same bucket.
		// To avoid an O(n^2) search backwards, we use the same trick here as
		// is used in induceSortS1, using the tail of the bucket as a counter
		// and right-shifting buckets that fill up. The logic is identical
		// (TODO: refactor this logic).
		c := ^S[i]
		switch {
		case SA[c] >= 0:
			// section 4.2 case 2
			val := SA[c]
			for x := c + 1; x < n; x++ {
				prev := val
				val = SA[x]
				SA[x] = prev
				if val < 0 && val != empty {
					break
				}
			}
			fallthrough

		case SA[c] == empty:
			// section 4.2 case 1
			if c-1 >= 0 && SA[c-1] == empty {
				SA[c-1] = i
				SA[c] = -1
			} else {
				SA[c] = i
			}
			break

		default:
			// section 4.2 case 3
			d := SA[c]
			pos := c + d - 1
			if pos >= 0 && SA[pos] == empty {
				SA[pos] = i
				SA[c]--
			} else {
				// right-shift SA[pos+1:c-1], inserting i into SA[pos+1]
				prev := i
				for x := pos + 1; x <= c; x++ {
					val := SA[x]
					SA[x] = prev
					prev = val
				}
			}
			break
		}
	}
	// Continuation of the bucket-tail-as-counter trick - we need
	// to fix any buckets that still have counters.
	for i := n - 1; i >= 0; i-- {
		if SA[i] == empty || SA[i] >= 0 {
			continue
		}
		d := SA[i]
		pos := i + d - 1
		prev := empty
		for x := pos + 1; x <= i; x++ {
			val := SA[x]
			SA[x] = prev
			prev = val
		}
	}

	// step 3 - induced sort the L-type suffixes of S into their buckets
	induceSortL1(S, SA)

	// step 4 - induced sort the S-type suffixes of S into their buckets
	induceSortS1(S, SA)

	// compact all the now-sorted LMS substrings into the first n1 positions of SA
	n1 := 0
	for i := 0; i < n; i++ {
		if SA[i] > 0 && // S[0] is not LMS by definition
			S[SA[i]] < 0 && // S[SA[i]] is S-type
			S[SA[i]-1] >= 0 { // S[SA[i-1]] is L-type
			// S[i] is LMS
			SA[n1] = SA[i]
			n1++
		}
	}

	// *********************************************
	// Stage 2: Rename the LMS substrings
	// *********************************************

	// provably, n1 is at most floor(n/2), so the following overlapping works
	SA1 := SA[:n1]  // SA1 overlaps the front of SA
	work := SA[n1:] // workspace overlaps the rest of SA
	S1 := SA[n-n1:] // S1 overlaps the end of SA (including part of "work", but rename deals with that correctly)
	k1 := rename1(S, SA1, work, S1)

	// *********************************************
	// Stage 3: Sort recursively
	// *********************************************
	if k1 == n1 {
		for i := 0; i < n1; i++ {
			SA1[S1[i]] = i
		}
	} else {
		computeSuffixArray1(S1, SA1, k1)
	}

	// NOT DESCRIBED IN PAPER BUT STILL NECESSARY (see SA-IS)
	// We need to undo the renaming of the LMS suffixes.
	// We no longer need S1, so reuse it to hold all the LMS indices.
	j := n1 - 1
	for i := n - 2; i >= 0; i-- {
		if S[i] >= 0 {
			// L-type; ignore
			continue
		}
		// S[i] is S-type; walk backwards to find LMS
		for i >= 1 && S[i-1] < 0 {
			// S[i-1] is also S-type; keep moving back
			i--
		}
		// S[0] is not LMS by definition, but otherwise S[i] is LMS
		if i > 0 {
			S1[j] = i
			j--
		}
	}
	if j != -1 {
		panic("didn't find all the LMS characters we expected")
	}
	// Now convert SA1 from renamed values to true values.
	for i := 0; i < n1; i++ {
		SA1[i] = S1[SA1[i]]
	}

	// *********************************************
	// Stage 4: Induced-sort SA(S) from SA1(S1)
	// *********************************************

	// step 1 - initialize SA[n1:] as empty
	setAllToEmpty(SA[n1:])

	// step 2 - put all the sorted LMS suffixes of S into their buckets in SA
	for i := n1 - 1; i >= 0; i-- {
		j := SA[i]
		SA[i] = empty
		c := ^S[j]
		if j == 0 {
			panic("unexpected j == 0")
		}
		// If we've worked our way back to c == i, then all the remaining
		// SA[0,c] values are already correct, and going into the loop below
		// with bucket counters will just screw things up.
		if c == i {
			SA[c] = j // restore it (we just emptied it out above...)
			break
		}

		// Same explanation for what's going on here as in Stage 1 step 2.
		switch {
		case SA[c] >= 0:
			val := SA[c]
			for x := c + 1; x < n; x++ {
				prev := val
				val = SA[x]
				SA[x] = prev
				if val < 0 && val != empty {
					break
				}
			}
			fallthrough

		case SA[c] == empty:
			// section 4.2 case 1
			if c-1 >= 0 && SA[c-1] == empty {
				SA[c-1] = j
				SA[c] = -1
			} else {
				SA[c] = j
			}
			break

		default:
			// section 4.2 case 3
			d := SA[c]
			pos := c + d - 1
			if pos >= 0 && SA[pos] == empty {
				SA[pos] = j
				SA[c]--
			} else {
				// right-shift SA[pos+1:c-1], inserting j into SA[pos+1]
				prev := j
				for x := pos + 1; x <= c; x++ {
					val := SA[x]
					SA[x] = prev
					prev = val
				}
			}
			break
		}
	}

	// Remove any leftover bucket counters and right-shift buckets.
	for i := n - 1; i >= 0; i-- {
		if SA[i] == empty || SA[i] >= 0 {
			continue
		}
		d := SA[i]
		pos := i + d - 1
		prev := empty
		for x := pos + 1; x <= i; x++ {
			val := SA[x]
			SA[x] = prev
			prev = val
		}
	}

	// step 3 - induced sort the L-type suffixes of S into their buckets
	induceSortL1(S, SA)

	// step 4 - induced sort the S-type suffixes of S into their buckets
	induceSortS1(S, SA)
}

// TODO pre-post
func induceSortL1(S, SA []int) {
	n := len(S)

	// special case to deal with the (virtual) sentinel:
	// S[n-1] is L-type because of the sentinel, and if we were treating
	// the sentinel as a real character, it would be at the front of SA[]
	// (it's effectively stored in "SA[-1]").
	//
	// Because c is L-type, we know SA[c] is empty, so we're in case 1 of section 4.1
	c := S[n-1]
	if c+1 < n && SA[c+1] == empty {
		SA[c+1] = n - 1
		SA[c] = -1
	} else {
		SA[c] = n - 1
	}

	for i := 0; i < n; i++ {
		if SA[i] < 0 {
			// SA[i] is empty or being used as a counter; nothing to do
			continue
		}
		j := SA[i] - 1
		// if we just grabbed the character before an LMS suffix, we need to clear
		// out that LMS suffix (induceSortS1 assumes only L-type suffixes are in SA)
		if S[SA[i]] < 0 {
			SA[i] = empty
		}
		if j < 0 {
			// SA[i] was == 0; there is no preceding character to look at
			continue
		}
		c := S[j]
		if c < 0 {
			// S[j] is S-type; move on
			continue
		}

		switch {
		case SA[c] >= 0:
			// section 4.1 case 2
			// left shift the previous bucket until we find the head
			// NOT MENTIONED IN PAPER: if we overwrite SA[i], we need
			// to *stay here* for the next iteration
			val := SA[c]
			overwroteSAi := (c == i)
			// TODO clean this up
			stop := false
			for x := c - 1; x >= 0 && !stop; x-- {
				prev := val
				val = SA[x]
				if val < 0 && val != empty {
					stop = true
				}
				SA[x] = prev
				if x == i {
					overwroteSAi = true
				}
			}
			if overwroteSAi {
				// decrement i; it will be incremented by the for loop, forcing us to look at SA[i] again next time
				i--
			}
			fallthrough // we now know SA[c] is empty so fall through

		case SA[c] == empty:
			// section 4.1 case 1
			if c+1 < n && SA[c+1] == empty {
				SA[c+1] = j
				SA[c] = -1
			} else {
				SA[c] = j
			}
			break

		default:
			// section 4.1 case 3 (SA[c] is a counter)
			d := SA[c]
			pos := c - d + 1
			if pos < n && SA[pos] == empty {
				SA[pos] = j
				SA[c]--
			} else {
				// left-shift SA[c+1:pos-1], inserting j into SA[pos-1]
				prev := j
				overwroteSAi := (c == i)
				for x := pos - 1; x >= c; x-- {
					val := SA[x]
					SA[x] = prev
					prev = val
					if x == i {
						overwroteSAi = true
					}
				}
				if overwroteSAi {
					i--
				}
			}
			break
		}
	}

	// NOT MENTIONED IN PAPER: We need to go back over SA and fix
	// any leftover counter values via left shifting the buckets appropriately.
	for i := 0; i < n; i++ {
		if SA[i] == empty || SA[i] >= 0 {
			continue
		}
		d := SA[i]
		pos := i - d + 1
		prev := empty
		for x := pos - 1; x >= i; x-- {
			val := SA[x]
			SA[x] = prev
			prev = val
		}
	}
}

// TODO pre-post
func induceSortS1(S, SA []int) {
	n := len(S)

	for i := n - 1; i >= 0; i-- {
		if SA[i] <= 0 {
			// SA[i] is empty or being used as a counter; nothing to do
			continue
		}
		j := SA[i] - 1
		c := ^S[j]
		if c < 0 {
			// S[j]==c is L-type; move on
			continue
		}

		switch {
		case SA[c] >= 0:
			// section 4.2 case 2
			val := SA[c]
			overwroteSAi := (c == i)
			stop := false
			for x := c + 1; x < n && !stop; x++ {
				prev := val
				val = SA[x]
				if val < 0 && val != empty {
					stop = true
				}
				SA[x] = prev
				if x == i {
					overwroteSAi = true
				}
			}
			if overwroteSAi {
				i++
			}
			fallthrough

		case SA[c] == empty:
			// section 4.2 case 1
			if c-1 >= 0 && SA[c-1] == empty {
				SA[c-1] = j
				SA[c] = -1
			} else {
				SA[c] = j
			}
			break

		default:
			// section 4.2 case 3
			d := SA[c]
			pos := c + d - 1
			if pos >= 0 && SA[pos] == empty {
				SA[pos] = j
				SA[c]--
			} else {
				// right-shift SA[pos+1:c-1], inserting j into SA[pos+1]
				prev := j
				overwroteSAi := (c == i) // TODO - can default to false?
				for x := pos + 1; x <= c; x++ {
					val := SA[x]
					SA[x] = prev
					prev = val
					if x == i {
						overwroteSAi = true
					}
				}
				if overwroteSAi {
					i++
				}
			}
			break
		}
	}
	// TODO PICKUP AT LINE 320
}
<|endoftext|>


<commit_before>/*
Copyright 2017 The Kubernetes 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 priorities

import (
	"fmt"

	"github.com/golang/glog"
	"k8s.io/api/core/v1"
	priorityutil "k8s.io/kubernetes/pkg/scheduler/algorithm/priorities/util"
	schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
	"k8s.io/kubernetes/pkg/scheduler/schedulercache"
)

type ResourceAllocationPriority struct {
	Name   string
	scorer func(requested, allocable *schedulercache.Resource) int64
}

func (r *ResourceAllocationPriority) PriorityMap(
	pod *v1.Pod,
	meta interface{},
	nodeInfo *schedulercache.NodeInfo) (schedulerapi.HostPriority, error) {
	node := nodeInfo.Node()
	if node == nil {
		return schedulerapi.HostPriority{}, fmt.Errorf("node not found")
	}
	allocatable := nodeInfo.AllocatableResource()

	var requested schedulercache.Resource
	if priorityMeta, ok := meta.(*priorityMetadata); ok {
		requested = *priorityMeta.nonZeroRequest
	} else {
		// We couldn't parse metadatat - fallback to computing it.
		requested = *getNonZeroRequests(pod)
	}

	requested.MilliCPU += nodeInfo.NonZeroRequest().MilliCPU
	requested.Memory += nodeInfo.NonZeroRequest().Memory

	score := r.scorer(&requested, &allocatable)

	if glog.V(10) {
		glog.Infof(
			"%v -> %v: %v, capacity %d millicores %d memory bytes, total request %d millicores %d memory bytes, score %d",
			pod.Name, node.Name, r.Name,
			allocatable.MilliCPU, allocatable.Memory,
			requested.MilliCPU+allocatable.MilliCPU, requested.Memory+allocatable.Memory,
			score,
		)
	}

	return schedulerapi.HostPriority{
		Host:  node.Name,
		Score: int(score),
	}, nil
}

func getNonZeroRequests(pod *v1.Pod) *schedulercache.Resource {
	result := &schedulercache.Resource{}
	for i := range pod.Spec.Containers {
		container := &pod.Spec.Containers[i]
		cpu, memory := priorityutil.GetNonzeroRequests(&container.Resources.Requests)
		result.MilliCPU += cpu
		result.Memory += memory
	}
	return result
}
<commit_msg>fix typo in resource_allocation.go<commit_after>/*
Copyright 2017 The Kubernetes 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 priorities

import (
	"fmt"

	"github.com/golang/glog"
	"k8s.io/api/core/v1"
	priorityutil "k8s.io/kubernetes/pkg/scheduler/algorithm/priorities/util"
	schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
	"k8s.io/kubernetes/pkg/scheduler/schedulercache"
)

type ResourceAllocationPriority struct {
	Name   string
	scorer func(requested, allocable *schedulercache.Resource) int64
}

func (r *ResourceAllocationPriority) PriorityMap(
	pod *v1.Pod,
	meta interface{},
	nodeInfo *schedulercache.NodeInfo) (schedulerapi.HostPriority, error) {
	node := nodeInfo.Node()
	if node == nil {
		return schedulerapi.HostPriority{}, fmt.Errorf("node not found")
	}
	allocatable := nodeInfo.AllocatableResource()

	var requested schedulercache.Resource
	if priorityMeta, ok := meta.(*priorityMetadata); ok {
		requested = *priorityMeta.nonZeroRequest
	} else {
		// We couldn't parse metadata - fallback to computing it.
		requested = *getNonZeroRequests(pod)
	}

	requested.MilliCPU += nodeInfo.NonZeroRequest().MilliCPU
	requested.Memory += nodeInfo.NonZeroRequest().Memory

	score := r.scorer(&requested, &allocatable)

	if glog.V(10) {
		glog.Infof(
			"%v -> %v: %v, capacity %d millicores %d memory bytes, total request %d millicores %d memory bytes, score %d",
			pod.Name, node.Name, r.Name,
			allocatable.MilliCPU, allocatable.Memory,
			requested.MilliCPU+allocatable.MilliCPU, requested.Memory+allocatable.Memory,
			score,
		)
	}

	return schedulerapi.HostPriority{
		Host:  node.Name,
		Score: int(score),
	}, nil
}

func getNonZeroRequests(pod *v1.Pod) *schedulercache.Resource {
	result := &schedulercache.Resource{}
	for i := range pod.Spec.Containers {
		container := &pod.Spec.Containers[i]
		cpu, memory := priorityutil.GetNonzeroRequests(&container.Resources.Requests)
		result.MilliCPU += cpu
		result.Memory += memory
	}
	return result
}
<|endoftext|>


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

package kvm

import (
	"fmt"
	"os/exec"
	"regexp"
	"strings"
)

var (
	// The regular expression for breaking up the results of 'virsh list'
	// (?m) - specify that this is a multiline regex
	// first part is the opaque identifier we don't care about
	// then the hostname, and lastly the status.
	machineListPattern = regexp.MustCompile(`(?m)^\s+\d+\s+(?P<hostname>[-\w]+)\s+(?P<status>.+)\s*$`)
)

// run the command and return the combined output.
func run(command string, args ...string) (output string, err error) {
	logger.Tracef("%s %v", command, args)
	cmd := exec.Command(command, args...)
	out, err := cmd.CombinedOutput()
	output = string(out)
	logger.Tracef("output: %v", output)
	if err != nil {
		return output, err
	}
	if !cmd.ProcessState.Success() {
		return output, fmt.Errorf("%s returned non-zero exi", command)
	}
	return output, nil
}

// SyncImages updates the local cached images by reading the simplestreams
// data and downloading the cloud images to the uvtool pool (used by libvirt).
func SyncImages(series string, arch string) error {
	args := []string{
		"sync",
		fmt.Sprintf("arch=%s", arch),
		fmt.Sprintf("release=%s", series),
	}
	_, err := run("uvt-simplestreams-libvirt", args...)
	return err
}

type CreateMachineParams struct {
	Hostname      string
	Series        string
	Arch          string
	UserData      string
	NetworkBridge string
	// TODO memory, cpu and disk
}

// CreateMachine creates a virtual machine and starts it.
func CreateMachine(params CreateMachineParams) error {
	if params.Hostname == "" {
		return fmt.Errorf("Hostname is required")
	}
	args := []string{
		"create",
		"--log-console-output", // do wonder where this goes...
	}
	if params.UserData != "" {
		args = append(args, "--user-data", params.UserData)
	}
	if params.NetworkBridge != "" {
		args = append(args, "--bridge", params.NetworkBridge)
	}
	// TODO add memory, cpu and disk prior to hostname
	args = append(args, params.Hostname)
	if params.Series != "" {
		args = append(args, fmt.Sprintf("release=%s", params.Series))
	}
	if params.Arch != "" {
		args = append(args, fmt.Sprintf("arch=%s", params.Arch))
	}
	output, err := run("uvt-kvm", args...)
	logger.Debugf("is this the logged output?:\n%s", output)
	return err
}

// DestroyMachine destroys the virtual machine identified by hostname.
func DestroyMachine(hostname string) error {
	_, err := run("uvt-kvm", "destroy", hostname)
	return err
}

// AutostartMachine indicates that the virtual machines should automatically
// restart when the host restarts.
func AutostartMachine(hostname string) error {
	_, err := run("virsh", "autostart", hostname)
	return err
}

// ListMachines returns a map of machine name to state, where state is one of:
// running, idle, paused, shutdown, shut off, crashed, dying, pmsuspended.
func ListMachines() (map[string]string, error) {
	output, err := run("virsh", "-q", "list", "--all")
	if err != nil {
		return nil, err
	}
	// Split the output into lines.
	// Perhaps regex matching is the easiest way to match the lines.
	//   id hostname status
	// separated by whitespace, with whitespace at the start too.
	result := make(map[string]string)
	for _, s := range machineListPattern.FindAllStringSubmatchIndex(output, -1) {
		machineStatus := machineListPattern.ExpandString(nil, "$hostname $status", output, s)
		parts := strings.SplitN(string(machineStatus), " ", 2)
		result[parts[0]] = parts[1]
	}
	return result, nil
}
<commit_msg>Add a bit more of a docstring.<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package kvm

// This file contains wrappers around the following executables:
//   uvt-simplestreams-libvirt
//   uvt-kvm
//   virsh
// Those executables are found in the following packages:
//   uvtool-libvirt
//   libvirt-bin
//
// These executables provide Juju's interface to dealing with kvm containers.
// The define how we start, stop and list running containers on the host

import (
	"fmt"
	"os/exec"
	"regexp"
	"strings"
)

var (
	// The regular expression for breaking up the results of 'virsh list'
	// (?m) - specify that this is a multiline regex
	// first part is the opaque identifier we don't care about
	// then the hostname, and lastly the status.
	machineListPattern = regexp.MustCompile(`(?m)^\s+\d+\s+(?P<hostname>[-\w]+)\s+(?P<status>.+)\s*$`)
)

// run the command and return the combined output.
func run(command string, args ...string) (output string, err error) {
	logger.Tracef("%s %v", command, args)
	cmd := exec.Command(command, args...)
	out, err := cmd.CombinedOutput()
	output = string(out)
	logger.Tracef("output: %v", output)
	if err != nil {
		return output, err
	}
	if !cmd.ProcessState.Success() {
		return output, fmt.Errorf("%s returned non-zero exi", command)
	}
	return output, nil
}

// SyncImages updates the local cached images by reading the simplestreams
// data and downloading the cloud images to the uvtool pool (used by libvirt).
func SyncImages(series string, arch string) error {
	args := []string{
		"sync",
		fmt.Sprintf("arch=%s", arch),
		fmt.Sprintf("release=%s", series),
	}
	_, err := run("uvt-simplestreams-libvirt", args...)
	return err
}

type CreateMachineParams struct {
	Hostname      string
	Series        string
	Arch          string
	UserData      string
	NetworkBridge string
	// TODO memory, cpu and disk
}

// CreateMachine creates a virtual machine and starts it.
func CreateMachine(params CreateMachineParams) error {
	if params.Hostname == "" {
		return fmt.Errorf("Hostname is required")
	}
	args := []string{
		"create",
		"--log-console-output", // do wonder where this goes...
	}
	if params.UserData != "" {
		args = append(args, "--user-data", params.UserData)
	}
	if params.NetworkBridge != "" {
		args = append(args, "--bridge", params.NetworkBridge)
	}
	// TODO add memory, cpu and disk prior to hostname
	args = append(args, params.Hostname)
	if params.Series != "" {
		args = append(args, fmt.Sprintf("release=%s", params.Series))
	}
	if params.Arch != "" {
		args = append(args, fmt.Sprintf("arch=%s", params.Arch))
	}
	output, err := run("uvt-kvm", args...)
	logger.Debugf("is this the logged output?:\n%s", output)
	return err
}

// DestroyMachine destroys the virtual machine identified by hostname.
func DestroyMachine(hostname string) error {
	_, err := run("uvt-kvm", "destroy", hostname)
	return err
}

// AutostartMachine indicates that the virtual machines should automatically
// restart when the host restarts.
func AutostartMachine(hostname string) error {
	_, err := run("virsh", "autostart", hostname)
	return err
}

// ListMachines returns a map of machine name to state, where state is one of:
// running, idle, paused, shutdown, shut off, crashed, dying, pmsuspended.
func ListMachines() (map[string]string, error) {
	output, err := run("virsh", "-q", "list", "--all")
	if err != nil {
		return nil, err
	}
	// Split the output into lines.
	// Perhaps regex matching is the easiest way to match the lines.
	//   id hostname status
	// separated by whitespace, with whitespace at the start too.
	result := make(map[string]string)
	for _, s := range machineListPattern.FindAllStringSubmatchIndex(output, -1) {
		machineStatus := machineListPattern.ExpandString(nil, "$hostname $status", output, s)
		parts := strings.SplitN(string(machineStatus), " ", 2)
		result[parts[0]] = parts[1]
	}
	return result, nil
}
<|endoftext|>


<commit_before>package transloadit

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"time"
)

type Config struct {
	AuthKey    string
	AuthSecret string
	Region     string
	Endpoint   string
}

var DefaultConfig = Config{
	Region:   "us-east-1",
	Endpoint: "http://api2.transloadit.com",
}

type Client struct {
	config     *Config
	httpClient *http.Client
}

type Response map[string]interface{}

type ListOptions struct {
	Page       int        `json:"page,omitempty"`
	PageSize   int        `json:"pagesize,omitempty"`
	Sort       string     `json:"sort,omitempty"`
	Order      string     `json:"order,omitempty"`
	Fields     []string   `json:"fields,omitempty"`
	Type       string     `json:"type,omitempty"`
	Keywords   []string   `json:"keyword,omitempty"`
	AssemblyId string     `json:"assembly_id,omitempty"`
	FromDate   *time.Time `json:"fromdate,omitempty"`
	ToDate     *time.Time `json:"todate,omitempty"`
	Auth       struct {
		Key     string `json:"key"`
		Expires string `json:"expires"`
	} `json:"auth"`
}

// Create a new client using the provided configuration object.
// An error will be returned if no AuthKey or AuthSecret is found in config.
func NewClient(config *Config) (*Client, error) {

	if config.AuthKey == "" {
		return nil, errors.New("failed to create client: missing AuthKey")
	}

	if config.AuthSecret == "" {
		return nil, errors.New("failed to create client: missing AuthSecret")
	}

	client := &Client{
		config:     config,
		httpClient: &http.Client{},
	}

	return client, nil

}

func (client *Client) sign(params map[string]interface{}) (string, string, error) {

	params["auth"] = map[string]string{
		"key":     client.config.AuthKey,
		"expires": getExpireString(),
	}

	b, err := json.Marshal(params)
	if err != nil {
		return "", "", fmt.Errorf("unable to create signature: %s", err)
	}

	hash := hmac.New(sha1.New, []byte(client.config.AuthSecret))
	hash.Write(b)
	return string(b), hex.EncodeToString(hash.Sum(nil)), nil

}

func (client *Client) doRequest(req *http.Request, result interface{}) (Response, error) {

	res, err := client.httpClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed execute http request: %s", err)
	}

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, fmt.Errorf("failed execute http request: %s", err)
	}

	if result == nil {
		var obj Response
		err = json.Unmarshal(body, &obj)
		if err != nil {
			return nil, fmt.Errorf("failed execute http request: %s", err)
		}

		if res.StatusCode != 200 {
			return obj, fmt.Errorf("failed execute http request: server responded with %s", obj["error"])
		}

		return obj, nil
	} else {
		err = json.Unmarshal(body, result)
		return nil, err
	}

	return nil, nil
}

func (client *Client) request(method string, path string, content map[string]interface{}, result interface{}) (Response, error) {

	uri := path
	// Don't add host for absolute urls
	if u, err := url.Parse(path); err == nil && u.Scheme == "" {
		uri = client.config.Endpoint + "/" + path
	}

	// Ensure content is a map
	if content == nil {
		content = make(map[string]interface{})
	}

	// Create signature
	params, signature, err := client.sign(content)
	if err != nil {
		return nil, fmt.Errorf("request: %s", err)
	}

	v := url.Values{}
	v.Set("params", params)
	v.Set("signature", signature)

	var body io.Reader
	if method == "GET" {
		uri += "?" + v.Encode()
	} else {
		body = strings.NewReader(v.Encode())
	}
	req, err := http.NewRequest(method, uri, body)
	if err != nil {
		return nil, fmt.Errorf("request: %s", err)
	}

	if method != "GET" {
		// Add content type header
		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	}

	return client.doRequest(req, result)
}

func (client *Client) listRequest(path string, options *ListOptions, result interface{}) (Response, error) {

	uri := client.config.Endpoint + "/" + path

	options.Auth = struct {
		Key     string `json:"key"`
		Expires string `json:"expires"`
	}{
		Key:     client.config.AuthKey,
		Expires: getExpireString(),
	}

	b, err := json.Marshal(options)
	if err != nil {
		return nil, fmt.Errorf("unable to create signature: %s", err)
	}

	hash := hmac.New(sha1.New, []byte(client.config.AuthSecret))
	hash.Write(b)

	params := string(b)
	signature := hex.EncodeToString(hash.Sum(nil))

	v := url.Values{}
	v.Set("params", params)
	v.Set("signature", signature)

	uri += "?" + v.Encode()

	req, err := http.NewRequest("GET", uri, nil)
	if err != nil {
		return nil, fmt.Errorf("request: %s", err)
	}

	return client.doRequest(req, result)

}

func getExpireString() string {

	// Expires in 1 hour
	expires := time.Now().UTC().Add(time.Hour)
	expiresStr := fmt.Sprintf("%04d/%02d/%02d %02d:%02d:%02d+00:00", expires.Year(), expires.Month(), expires.Day(), expires.Hour(), expires.Minute(), expires.Second())
	return string(expiresStr)

}
<commit_msg>Remove unneeded fix for unsupported go1<commit_after>package transloadit

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"time"
)

type Config struct {
	AuthKey    string
	AuthSecret string
	Region     string
	Endpoint   string
}

var DefaultConfig = Config{
	Region:   "us-east-1",
	Endpoint: "http://api2.transloadit.com",
}

type Client struct {
	config     *Config
	httpClient *http.Client
}

type Response map[string]interface{}

type ListOptions struct {
	Page       int        `json:"page,omitempty"`
	PageSize   int        `json:"pagesize,omitempty"`
	Sort       string     `json:"sort,omitempty"`
	Order      string     `json:"order,omitempty"`
	Fields     []string   `json:"fields,omitempty"`
	Type       string     `json:"type,omitempty"`
	Keywords   []string   `json:"keyword,omitempty"`
	AssemblyId string     `json:"assembly_id,omitempty"`
	FromDate   *time.Time `json:"fromdate,omitempty"`
	ToDate     *time.Time `json:"todate,omitempty"`
	Auth       struct {
		Key     string `json:"key"`
		Expires string `json:"expires"`
	} `json:"auth"`
}

// Create a new client using the provided configuration object.
// An error will be returned if no AuthKey or AuthSecret is found in config.
func NewClient(config *Config) (*Client, error) {

	if config.AuthKey == "" {
		return nil, errors.New("failed to create client: missing AuthKey")
	}

	if config.AuthSecret == "" {
		return nil, errors.New("failed to create client: missing AuthSecret")
	}

	client := &Client{
		config:     config,
		httpClient: &http.Client{},
	}

	return client, nil

}

func (client *Client) sign(params map[string]interface{}) (string, string, error) {

	params["auth"] = map[string]string{
		"key":     client.config.AuthKey,
		"expires": getExpireString(),
	}

	b, err := json.Marshal(params)
	if err != nil {
		return "", "", fmt.Errorf("unable to create signature: %s", err)
	}

	hash := hmac.New(sha1.New, []byte(client.config.AuthSecret))
	hash.Write(b)
	return string(b), hex.EncodeToString(hash.Sum(nil)), nil

}

func (client *Client) doRequest(req *http.Request, result interface{}) (Response, error) {

	res, err := client.httpClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed execute http request: %s", err)
	}

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, fmt.Errorf("failed execute http request: %s", err)
	}

	if result == nil {
		var obj Response
		err = json.Unmarshal(body, &obj)
		if err != nil {
			return nil, fmt.Errorf("failed execute http request: %s", err)
		}

		if res.StatusCode != 200 {
			return obj, fmt.Errorf("failed execute http request: server responded with %s", obj["error"])
		}

		return obj, nil
	} else {
		err = json.Unmarshal(body, result)
		return nil, err
	}
}

func (client *Client) request(method string, path string, content map[string]interface{}, result interface{}) (Response, error) {

	uri := path
	// Don't add host for absolute urls
	if u, err := url.Parse(path); err == nil && u.Scheme == "" {
		uri = client.config.Endpoint + "/" + path
	}

	// Ensure content is a map
	if content == nil {
		content = make(map[string]interface{})
	}

	// Create signature
	params, signature, err := client.sign(content)
	if err != nil {
		return nil, fmt.Errorf("request: %s", err)
	}

	v := url.Values{}
	v.Set("params", params)
	v.Set("signature", signature)

	var body io.Reader
	if method == "GET" {
		uri += "?" + v.Encode()
	} else {
		body = strings.NewReader(v.Encode())
	}
	req, err := http.NewRequest(method, uri, body)
	if err != nil {
		return nil, fmt.Errorf("request: %s", err)
	}

	if method != "GET" {
		// Add content type header
		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	}

	return client.doRequest(req, result)
}

func (client *Client) listRequest(path string, options *ListOptions, result interface{}) (Response, error) {

	uri := client.config.Endpoint + "/" + path

	options.Auth = struct {
		Key     string `json:"key"`
		Expires string `json:"expires"`
	}{
		Key:     client.config.AuthKey,
		Expires: getExpireString(),
	}

	b, err := json.Marshal(options)
	if err != nil {
		return nil, fmt.Errorf("unable to create signature: %s", err)
	}

	hash := hmac.New(sha1.New, []byte(client.config.AuthSecret))
	hash.Write(b)

	params := string(b)
	signature := hex.EncodeToString(hash.Sum(nil))

	v := url.Values{}
	v.Set("params", params)
	v.Set("signature", signature)

	uri += "?" + v.Encode()

	req, err := http.NewRequest("GET", uri, nil)
	if err != nil {
		return nil, fmt.Errorf("request: %s", err)
	}

	return client.doRequest(req, result)

}

func getExpireString() string {

	// Expires in 1 hour
	expires := time.Now().UTC().Add(time.Hour)
	expiresStr := fmt.Sprintf("%04d/%02d/%02d %02d:%02d:%02d+00:00", expires.Year(), expires.Month(), expires.Day(), expires.Hour(), expires.Minute(), expires.Second())
	return string(expiresStr)

}
<|endoftext|>


<commit_before>// Package alice implements a middleware chaining solution.
package alice

import (
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/stretchr/testify/assert"
)

// A constructor for middleware
// that writes its own "tag" into the RW and does nothing else.
// Useful in checking if a chain is behaving in the right order.
func tagMiddleware(tag string) Constructor {
	return func(h http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Write([]byte(tag))
			h.ServeHTTP(w, r)
		})
	}
}

var testApp = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("app\n"))
})

// Tests creating a new chain
func TestNew(t *testing.T) {
	c1 := func(h http.Handler) http.Handler {
		return nil
	}
	c2 := func(h http.Handler) http.Handler {
		return http.StripPrefix("potato", nil)
	}

	slice := []Constructor{c1, c2}

	chain := New(slice...)
	assert.Equal(t, chain.constructors[0], slice[0])
	assert.Equal(t, chain.constructors[1], slice[1])
}

func TestThenWorksWithNoMiddleware(t *testing.T) {
	assert.NotPanics(t, func() {
		chain := New()
		final := chain.Then(testApp)

		assert.Equal(t, final, testApp)
	})
}

func TestThenTreatsNilAsDefaultServeMux(t *testing.T) {
	chained := New().Then(nil)
	assert.Equal(t, chained, http.DefaultServeMux)
}

func TestThenFuncTreatsNilAsDefaultServeMux(t *testing.T) {
	chained := New().ThenFunc(nil)
	assert.Equal(t, chained, http.DefaultServeMux)
}

func TestThenOrdersHandlersRight(t *testing.T) {
	t1 := tagMiddleware("t1\n")
	t2 := tagMiddleware("t2\n")
	t3 := tagMiddleware("t3\n")

	chained := New(t1, t2, t3).Then(testApp)

	w := httptest.NewRecorder()
	r, err := http.NewRequest("GET", "/", nil)
	if err != nil {
		t.Fatal(err)
	}

	chained.ServeHTTP(w, r)

	assert.Equal(t, w.Body.String(), "t1\nt2\nt3\napp\n")
}

func TestAppendAddsHandlersCorrectly(t *testing.T) {
	chain := New(tagMiddleware("t1\n"), tagMiddleware("t2\n"))
	newChain := chain.Append(tagMiddleware("t3\n"), tagMiddleware("t4\n"))

	assert.Equal(t, len(chain.constructors), 2)
	assert.Equal(t, len(newChain.constructors), 4)

	chained := newChain.Then(testApp)

	w := httptest.NewRecorder()
	r, err := http.NewRequest("GET", "/", nil)
	if err != nil {
		t.Fatal(err)
	}

	chained.ServeHTTP(w, r)

	assert.Equal(t, w.Body.String(), "t1\nt2\nt3\nt4\napp\n")
}

func TestAppendRespectsImmutability(t *testing.T) {
	chain := New(tagMiddleware(""))
	newChain := chain.Append(tagMiddleware(""))

	assert.NotEqual(t, &chain.constructors[0], &newChain.constructors[0])
}
<commit_msg>Roll our own method of comparing functions.<commit_after>// Package alice implements a middleware chaining solution.
package alice

import (
	"net/http"
	"net/http/httptest"
	"reflect"
	"testing"

	"github.com/stretchr/testify/assert"
)

// A constructor for middleware
// that writes its own "tag" into the RW and does nothing else.
// Useful in checking if a chain is behaving in the right order.
func tagMiddleware(tag string) Constructor {
	return func(h http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Write([]byte(tag))
			h.ServeHTTP(w, r)
		})
	}
}

// Not recommended (https://golang.org/pkg/reflect/#Value.Pointer),
// but the best we can do.
func funcsEqual(f1, f2 interface{}) bool {
	val1 := reflect.ValueOf(f1)
	val2 := reflect.ValueOf(f2)
	return val1.Pointer() == val2.Pointer()
}

var testApp = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("app\n"))
})

// Tests creating a new chain
func TestNew(t *testing.T) {
	c1 := func(h http.Handler) http.Handler {
		return nil
	}
	c2 := func(h http.Handler) http.Handler {
		return http.StripPrefix("potato", nil)
	}

	slice := []Constructor{c1, c2}

	chain := New(slice...)
	assert.True(t, funcsEqual(chain.constructors[0], slice[0]))
	assert.True(t, funcsEqual(chain.constructors[1], slice[1]))
}

func TestThenWorksWithNoMiddleware(t *testing.T) {
	assert.NotPanics(t, func() {
		chain := New()
		final := chain.Then(testApp)

		assert.True(t, funcsEqual(final, testApp))
	})
}

func TestThenTreatsNilAsDefaultServeMux(t *testing.T) {
	chained := New().Then(nil)
	assert.Equal(t, chained, http.DefaultServeMux)
}

func TestThenFuncTreatsNilAsDefaultServeMux(t *testing.T) {
	chained := New().ThenFunc(nil)
	assert.Equal(t, chained, http.DefaultServeMux)
}

func TestThenOrdersHandlersRight(t *testing.T) {
	t1 := tagMiddleware("t1\n")
	t2 := tagMiddleware("t2\n")
	t3 := tagMiddleware("t3\n")

	chained := New(t1, t2, t3).Then(testApp)

	w := httptest.NewRecorder()
	r, err := http.NewRequest("GET", "/", nil)
	if err != nil {
		t.Fatal(err)
	}

	chained.ServeHTTP(w, r)

	assert.Equal(t, w.Body.String(), "t1\nt2\nt3\napp\n")
}

func TestAppendAddsHandlersCorrectly(t *testing.T) {
	chain := New(tagMiddleware("t1\n"), tagMiddleware("t2\n"))
	newChain := chain.Append(tagMiddleware("t3\n"), tagMiddleware("t4\n"))

	assert.Equal(t, len(chain.constructors), 2)
	assert.Equal(t, len(newChain.constructors), 4)

	chained := newChain.Then(testApp)

	w := httptest.NewRecorder()
	r, err := http.NewRequest("GET", "/", nil)
	if err != nil {
		t.Fatal(err)
	}

	chained.ServeHTTP(w, r)

	assert.Equal(t, w.Body.String(), "t1\nt2\nt3\nt4\napp\n")
}

func TestAppendRespectsImmutability(t *testing.T) {
	chain := New(tagMiddleware(""))
	newChain := chain.Append(tagMiddleware(""))

	assert.NotEqual(t, &chain.constructors[0], &newChain.constructors[0])
}
<|endoftext|>


<commit_before>// Copyright 2020 The Prometheus 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 httputil

import (
	"context"
	"net"
	"net/http"

	"github.com/prometheus/prometheus/promql"
)

type ctxParam int

var pathParam ctxParam

// ContextWithPath returns a new context with the given path to be used later
// when logging the query.
func ContextWithPath(ctx context.Context, path string) context.Context {
	return context.WithValue(ctx, pathParam, path)
}

// ContextFromRequest returns a new context from a requests with identifiers of
// the request to be used later when logging the query.
func ContextFromRequest(ctx context.Context, r *http.Request) context.Context {
	reqCtxVal := map[string]string{
		"method": r.Method,
	}

	// r.RemoteAddr has no defined format, so don't return error if we cannot split it into IP:Port.
	ip, _, _ := net.SplitHostPort(r.RemoteAddr)
	if ip != "" {
		reqCtxVal["clientIP"] = ip
	}

	var path string
	if v := ctx.Value(pathParam); v != nil {
		path = v.(string)
		reqCtxVal["path"] = path
	}

	return promql.NewOriginContext(ctx, map[string]interface{}{
		"httpRequest": reqCtxVal,
	})
}
<commit_msg>Updated comment.<commit_after>// Copyright 2020 The Prometheus 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 httputil

import (
	"context"
	"net"
	"net/http"

	"github.com/prometheus/prometheus/promql"
)

type ctxParam int

var pathParam ctxParam

// ContextWithPath returns a new context with the given path to be used later
// when logging the query.
func ContextWithPath(ctx context.Context, path string) context.Context {
	return context.WithValue(ctx, pathParam, path)
}

// ContextFromRequest returns a new context with identifiers of
// the request to be used later when logging the query.
func ContextFromRequest(ctx context.Context, r *http.Request) context.Context {
	reqCtxVal := map[string]string{
		"method": r.Method,
	}

	// r.RemoteAddr has no defined format, so don't return error if we cannot split it into IP:Port.
	ip, _, _ := net.SplitHostPort(r.RemoteAddr)
	if ip != "" {
		reqCtxVal["clientIP"] = ip
	}

	var path string
	if v := ctx.Value(pathParam); v != nil {
		path = v.(string)
		reqCtxVal["path"] = path
	}

	return promql.NewOriginContext(ctx, map[string]interface{}{
		"httpRequest": reqCtxVal,
	})
}
<|endoftext|>


<commit_before>// Copyright (C) 2014 Miquel Sabaté Solà
// This file is licensed under the MIT license.
// See the LICENSE file.

package lib

import (
	"database/sql"
	"encoding/json"
	"io/ioutil"

	"github.com/coopernurse/gorp"
	_ "github.com/lib/pq"
)

// Public: get the configuration of the database for the current environment.
//
// file - The name of the JSON file describing the database configuration.
//
// Returns a string that it's supposed to be passed as the second argument
// of the sql.Open function.
func DBConfig(file string) string {
	// Read the contents and unmarshal the thing.
	root := FindRoot("vendrell", ".")
	contents, _ := ioutil.ReadFile(root + "/db/" + file)
	m := map[string]map[string]string{}
	json.Unmarshal(contents, &m)

	// Put it in a fancy string.
	current := m[Env()]
	size := len(current)
	cfg := ""
	i := 0
	for key, value := range current {
		if value != "" {
			cfg += key + "=" + value
			if i != size-1 {
				cfg += " "
			}
		}
		i++
	}
	return cfg
}

// Public: initializes the global Db variable.
//
// file - The name of the JSON file describing the database configuration.
//
// Returns a new DB instance.
func InitDB(file string) gorp.DbMap {
	d, err := sql.Open("postgres", DBConfig(file))
	if err != nil {
		panic(err)
	}
	return gorp.DbMap{Db: d, Dialect: gorp.PostgresDialect{}}
}
<commit_msg>lib: trim the space from the DB config line.<commit_after>// Copyright (C) 2014 Miquel Sabaté Solà
// This file is licensed under the MIT license.
// See the LICENSE file.

package lib

import (
	"database/sql"
	"encoding/json"
	"io/ioutil"
	"strings"

	"github.com/coopernurse/gorp"
	_ "github.com/lib/pq"
)

// Public: get the configuration of the database for the current environment.
//
// file - The name of the JSON file describing the database configuration.
//
// Returns a string that it's supposed to be passed as the second argument
// of the sql.Open function.
func DBConfig(file string) string {
	// Read the contents and unmarshal the thing.
	root := FindRoot("vendrell", ".")
	contents, _ := ioutil.ReadFile(root + "/db/" + file)
	m := map[string]map[string]string{}
	json.Unmarshal(contents, &m)

	// Put it in a fancy string.
	current := m[Env()]
	size := len(current)
	cfg := ""
	i := 0
	for key, value := range current {
		if value != "" {
			cfg += key + "=" + value
			if i != size-1 {
				cfg += " "
			}
		}
		i++
	}
	return strings.TrimSpace(cfg)
}

// Public: initializes the global Db variable.
//
// file - The name of the JSON file describing the database configuration.
//
// Returns a new DB instance.
func InitDB(file string) gorp.DbMap {
	d, err := sql.Open("postgres", DBConfig(file))
	if err != nil {
		panic(err)
	}
	return gorp.DbMap{Db: d, Dialect: gorp.PostgresDialect{}}
}
<|endoftext|>


<commit_before>package incata

import (
	"database/sql/driver"
	"testing"

	//"github.com/DATA-DOG/go-sqlmock"
	"github.com/satori/go.uuid"
)

type AnyType struct{}

// Match satisfies sqlmock.Argument interface
func (a AnyType) Match(v driver.Value) bool {
	return true
}

func TestSqlReaderRead(t *testing.T) {

	t.SkipNow()
	//
	// 	db, mock, err := sqlmock.New()
	// 	if err != nil {
	// 		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
	// 	}
	// 	defer db.Close()
	//
	// 	var sourceID = uuid.NewV4()
	//
	// 	rows := sqlmock.NewRows([]string{"Id", "SourceId", "Created", "EventType", "Version", "Payload"})
	//
	// 	mock.ExpectQuery("SELECT").WithArgs(sourceID.String()).WillReturnRows(rows)
	//
	// 	storage, _ := NewDbFinalized(db, MSSQL)
	// 	marshaller := NewJSONMarshaller()
	// 	reader := NewSQLReader(storage, marshaller)

	// 	_, err = reader.Read(sourceID)
	// 	if err != nil {
	// 		t.Fatalf("unexpected err: %s", err)
	// 	}
	//
	// 	if err = mock.ExpectationsWereMet(); err != nil {
	// 		t.Fatalf("there were unfulfilled expections: %s", err)
	// 	}
}

func TestUnmarshalUUID(t *testing.T) {

	srcID := uuid.NewV4()

	srcIDBytes := srcID.Bytes()

	var srcIDResult uuid.UUID

	srcIDResult, _ = uuid.FromBytes(srcIDBytes)

	if !uuid.Equal(srcID, srcIDResult) {
		t.Fatalf("are not equal %s %s", srcID, srcIDResult)
	}
}
<commit_msg>readded test<commit_after>package incata

import (
	"database/sql/driver"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
	"github.com/satori/go.uuid"
	"time"
)

type AnyType struct{}

// Match satisfies sqlmock.Argument interface
func (a AnyType) Match(v driver.Value) bool {
	return true
}

func TestSqlReaderRead(t *testing.T) {

	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
	}
	defer db.Close()

	var sourceID = uuid.NewV4()

	rows := sqlmock.NewRows([]string{"Id", "SourceId", "Created", "EventType", "Version", "Payload"}).AddRow(1, uuid.NewV4().String(), time.Now, "Test", 1, "123")

	mock.ExpectQuery("SELECT").WithArgs(sourceID.String()).WillReturnRows(rows)

	storage, _ := NewDbFinalized(db, MSSQL)
	marshaller := NewJSONMarshaller()
	reader := NewSQLReader(storage, marshaller)

	_, err = reader.Read(sourceID)
	if err != nil {
		t.Fatalf("unexpected err: %s", err)
	}

	if err = mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("there were unfulfilled expections: %s", err)
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"

	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func resourceAwsVpcPeeringConnectionAccepter() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsVPCPeeringAccepterCreate,
		Read:   resourceAwsVPCPeeringRead,
		Update: resourceAwsVPCPeeringUpdate,
		Delete: resourceAwsVPCPeeringAccepterDelete,
		Importer: &schema.ResourceImporter{
			State: func(d *schema.ResourceData, m interface{}) (result []*schema.ResourceData, err error) {
				d.Set("vpc_peering_connection_id", d.Id())

				return []*schema.ResourceData{d}, nil
			},
		},

		Schema: map[string]*schema.Schema{
			"vpc_peering_connection_id": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"auto_accept": {
				Type:     schema.TypeBool,
				Optional: true,
			},
			"accept_status": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"vpc_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"peer_vpc_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"peer_owner_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"peer_region": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"accepter":  vpcPeeringConnectionOptionsSchema(),
			"requester": vpcPeeringConnectionOptionsSchema(),
			"tags":      tagsSchema(),
		},
	}
}

func resourceAwsVPCPeeringAccepterCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	id := d.Get("vpc_peering_connection_id").(string)
	d.SetId(id)

	if err := resourceAwsVPCPeeringRead(d, meta); err != nil {
		return err
	}
	if d.Id() == "" {
		return fmt.Errorf("VPC Peering Connection %q not found", id)
	}

	if v := d.Get("tags").(map[string]interface{}); len(v) > 0 {
		if err := keyvaluetags.Ec2CreateTags(conn, d.Id(), v); err != nil {
			return fmt.Errorf("error adding tags: %s", err)
		}
	}

	return resourceAwsVPCPeeringUpdate(d, meta)
}

func resourceAwsVPCPeeringAccepterDelete(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[WARN] Will not delete VPC peering connection. Terraform will remove this resource from the state file, however resources may remain.")
	return nil
}
<commit_msg>resource/aws_vpc_peering_connection_accepter: Do not overwrite incoming ResourceData on creation<commit_after>package aws

import (
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func resourceAwsVpcPeeringConnectionAccepter() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsVPCPeeringAccepterCreate,
		Read:   resourceAwsVPCPeeringRead,
		Update: resourceAwsVPCPeeringUpdate,
		Delete: resourceAwsVPCPeeringAccepterDelete,
		Importer: &schema.ResourceImporter{
			State: func(d *schema.ResourceData, m interface{}) (result []*schema.ResourceData, err error) {
				d.Set("vpc_peering_connection_id", d.Id())

				return []*schema.ResourceData{d}, nil
			},
		},

		Schema: map[string]*schema.Schema{
			"vpc_peering_connection_id": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"auto_accept": {
				Type:     schema.TypeBool,
				Optional: true,
			},
			"accept_status": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"vpc_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"peer_vpc_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"peer_owner_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"peer_region": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"accepter":  vpcPeeringConnectionOptionsSchema(),
			"requester": vpcPeeringConnectionOptionsSchema(),
			"tags":      tagsSchema(),
		},
	}
}

func resourceAwsVPCPeeringAccepterCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	id := d.Get("vpc_peering_connection_id").(string)

	_, statusCode, err := vpcPeeringConnectionRefreshState(conn, id)()

	if err != nil && statusCode != ec2.VpcPeeringConnectionStateReasonCodeFailed {
		return fmt.Errorf("error reading VPC Peering Connection (%s): %s", id, err)
	}

	status := map[string]bool{
		ec2.VpcPeeringConnectionStateReasonCodeDeleted:  true,
		ec2.VpcPeeringConnectionStateReasonCodeDeleting: true,
		ec2.VpcPeeringConnectionStateReasonCodeExpired:  true,
		ec2.VpcPeeringConnectionStateReasonCodeFailed:   true,
		ec2.VpcPeeringConnectionStateReasonCodeRejected: true,
		"": true, // AWS consistency issue, see vpcPeeringConnectionRefreshState
	}
	if _, ok := status[statusCode]; ok {
		return fmt.Errorf("VPC Peering Connection (%s) in unexpected status for acceptance: %s", id, statusCode)
	}

	d.SetId(id)

	if v := d.Get("tags").(map[string]interface{}); len(v) > 0 {
		if err := keyvaluetags.Ec2CreateTags(conn, d.Id(), v); err != nil {
			return fmt.Errorf("error adding tags: %s", err)
		}
	}

	return resourceAwsVPCPeeringUpdate(d, meta)
}

func resourceAwsVPCPeeringAccepterDelete(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[WARN] Will not delete VPC peering connection. Terraform will remove this resource from the state file, however resources may remain.")
	return nil
}
<|endoftext|>


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

package ssh

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"os/exec"
	"strings"

	"launchpad.net/juju-core/utils"
)

var opensshCommonOptions = map[string][]string{"-o": []string{"StrictHostKeyChecking no"}}

// default identities will not be attempted if
// -i is specified and they are not explcitly
// included.
var defaultIdentities = []string{
	"~/.ssh/identity",
	"~/.ssh/id_rsa",
	"~/.ssh/id_dsa",
	"~/.ssh/id_ecdsa",
}

type opensshCommandKind int

const (
	sshKind opensshCommandKind = iota
	scpKind
)

// sshpassWrap wraps the command/args with sshpass if it is found in $PATH
// and the SSHPASS environment variable is set. Otherwise, the original
// command/args are returned.
func sshpassWrap(cmd string, args []string) (string, []string) {
	if os.Getenv("SSHPASS") != "" {
		if path, err := exec.LookPath("sshpass"); err == nil {
			return path, append([]string{"-e", cmd}, args...)
		}
	}
	return cmd, args
}

// OpenSSHClient is an implementation of Client that
// uses the ssh and scp executables found in $PATH.
type OpenSSHClient struct{}

// NewOpenSSHClient creates a new OpenSSHClient.
// If the ssh and scp programs cannot be found
// in $PATH, then an error is returned.
func NewOpenSSHClient() (*OpenSSHClient, error) {
	var c OpenSSHClient
	if _, err := exec.LookPath("ssh"); err != nil {
		return nil, err
	}
	if _, err := exec.LookPath("scp"); err != nil {
		return nil, err
	}
	return &c, nil
}

func opensshOptions(options *Options, commandKind opensshCommandKind) map[string][]string {
	args := make(map[string][]string)
	for k, v := range opensshCommonOptions {
		args[k] = v
	}
	if options == nil {
		options = &Options{}
	}
	if len(options.proxyCommand) > 0 {
		args["-o"] = append(args["-o"], "ProxyCommand "+utils.CommandString(options.proxyCommand...))
	}
	if !options.passwordAuthAllowed {
		args["-o"] = append(args["-o"], "PasswordAuthentication no")
	}
	if options.allocatePTY {
		args["-t"] = []string{}
	}
	identities := append([]string{}, options.identities...)
	if pk := PrivateKeyFiles(); len(pk) > 0 {
		// Add client keys as implicit identities
		identities = append(identities, pk...)
	}
	// If any identities are specified, the
	// default ones must be explicitly specified.
	if len(identities) > 0 {
		for _, identity := range defaultIdentities {
			path, err := utils.NormalizePath(identity)
			if err != nil {
				logger.Warningf("failed to normalize path %q: %v", identity, err)
				continue
			}
			if _, err := os.Stat(path); err == nil {
				identities = append(identities, path)
			}
		}
	}
	for _, identity := range identities {
		args["-i"] = append(args["-i"], identity)
	}
	if options.port != 0 {
		port := fmt.Sprint(options.port)
		if commandKind == scpKind {
			// scp uses -P instead of -p (-p means preserve).
			args["-P"] = []string{port}
		} else {
			args["-p"] = []string{port}
		}
	}
	return args
}

func expandArgs(args map[string][]string, quote bool) []string {
	var list []string
	for opt, vals := range args {
		if len(vals) == 0 {
			list = append(list, opt)
			if opt == "-t" {
				// In order to force a PTY to be allocated, we need to
				// pass -t twice.
				list = append(list, opt)
			}
		}
		for _, val := range vals {
			list = append(list, opt)
			if quote {
				val = fmt.Sprintf("%q", val)
			}
			list = append(list, val)
		}
	}
	return list
}

// Command implements Client.Command.
func (c *OpenSSHClient) Command(host string, command []string, options *Options) *Cmd {
	opts := opensshOptions(options, sshKind)
	args := expandArgs(opts, false)
	args = append(args, host)
	if len(command) > 0 {
		args = append(args, command...)
	}
	bin, args := sshpassWrap("ssh", args)
	optsList := strings.Join(expandArgs(opts, true), " ")
	fullCommand := strings.Join(command, " ")
	logger.Debugf("running: %s %s %q '%s'", bin, optsList, host, fullCommand)
	return &Cmd{impl: &opensshCmd{exec.Command(bin, args...)}}
}

// Copy implements Client.Copy.
func (c *OpenSSHClient) Copy(targets, extraArgs []string, userOptions *Options) error {
	var options Options
	if userOptions != nil {
		options = *userOptions
		options.allocatePTY = false // doesn't make sense for scp
	}
	opts := opensshOptions(&options, scpKind)
	args := expandArgs(opts, false)
	args = append(args, extraArgs...)
	args = append(args, targets...)
	bin, args := sshpassWrap("scp", args)
	cmd := exec.Command(bin, args...)
	var stderr bytes.Buffer
	cmd.Stderr = &stderr
	allOpts := append(expandArgs(opts, true), extraArgs...)
	optsList := strings.Join(allOpts, " ")
	targetList := `"` + strings.Join(targets, `" "`) + `"`
	logger.Debugf("running: %s %s %s", bin, optsList, targetList)
	if err := cmd.Run(); err != nil {
		stderr := strings.TrimSpace(stderr.String())
		if len(stderr) > 0 {
			err = fmt.Errorf("%v (%v)", err, stderr)
		}
		return err
	}
	return nil
}

type opensshCmd struct {
	*exec.Cmd
}

func (c *opensshCmd) SetStdio(stdin io.Reader, stdout, stderr io.Writer) {
	c.Stdin, c.Stdout, c.Stderr = stdin, stdout, stderr
}

func (c *opensshCmd) StdinPipe() (io.WriteCloser, io.Reader, error) {
	wc, err := c.Cmd.StdinPipe()
	if err != nil {
		return nil, nil, err
	}
	return wc, c.Stdin, nil
}

func (c *opensshCmd) StdoutPipe() (io.ReadCloser, io.Writer, error) {
	rc, err := c.Cmd.StdoutPipe()
	if err != nil {
		return nil, nil, err
	}
	return rc, c.Stdout, nil
}

func (c *opensshCmd) StderrPipe() (io.ReadCloser, io.Writer, error) {
	rc, err := c.Cmd.StderrPipe()
	if err != nil {
		return nil, nil, err
	}
	return rc, c.Stderr, nil
}

func (c *opensshCmd) Kill() error {
	if c.Process == nil {
		return fmt.Errorf("process has not been started")
	}
	return c.Process.Kill()
}
<commit_msg>utils/ssh: revert to using slices for command args<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package ssh

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"os/exec"
	"strings"

	"launchpad.net/juju-core/utils"
)

var opensshCommonOptions = []string{"-o", "StrictHostKeyChecking no"}

// default identities will not be attempted if
// -i is specified and they are not explcitly
// included.
var defaultIdentities = []string{
	"~/.ssh/identity",
	"~/.ssh/id_rsa",
	"~/.ssh/id_dsa",
	"~/.ssh/id_ecdsa",
}

type opensshCommandKind int

const (
	sshKind opensshCommandKind = iota
	scpKind
)

// sshpassWrap wraps the command/args with sshpass if it is found in $PATH
// and the SSHPASS environment variable is set. Otherwise, the original
// command/args are returned.
func sshpassWrap(cmd string, args []string) (string, []string) {
	if os.Getenv("SSHPASS") != "" {
		if path, err := exec.LookPath("sshpass"); err == nil {
			return path, append([]string{"-e", cmd}, args...)
		}
	}
	return cmd, args
}

// OpenSSHClient is an implementation of Client that
// uses the ssh and scp executables found in $PATH.
type OpenSSHClient struct{}

// NewOpenSSHClient creates a new OpenSSHClient.
// If the ssh and scp programs cannot be found
// in $PATH, then an error is returned.
func NewOpenSSHClient() (*OpenSSHClient, error) {
	var c OpenSSHClient
	if _, err := exec.LookPath("ssh"); err != nil {
		return nil, err
	}
	if _, err := exec.LookPath("scp"); err != nil {
		return nil, err
	}
	return &c, nil
}

func opensshOptions(options *Options, commandKind opensshCommandKind) []string {
	args := append([]string{}, opensshCommonOptions...)
	if options == nil {
		options = &Options{}
	}
	if len(options.proxyCommand) > 0 {
		args = append(args, "-o", "ProxyCommand "+utils.CommandString(options.proxyCommand...))
	}
	if !options.passwordAuthAllowed {
		args = append(args, "-o", "PasswordAuthentication no")
	}
	if options.allocatePTY {
		args = append(args, "-t", "-t") // twice to force
	}
	identities := append([]string{}, options.identities...)
	if pk := PrivateKeyFiles(); len(pk) > 0 {
		// Add client keys as implicit identities
		identities = append(identities, pk...)
	}
	// If any identities are specified, the
	// default ones must be explicitly specified.
	if len(identities) > 0 {
		for _, identity := range defaultIdentities {
			path, err := utils.NormalizePath(identity)
			if err != nil {
				logger.Warningf("failed to normalize path %q: %v", identity, err)
				continue
			}
			if _, err := os.Stat(path); err == nil {
				identities = append(identities, path)
			}
		}
	}
	for _, identity := range identities {
		args = append(args, "-i", identity)
	}
	if options.port != 0 {
		port := fmt.Sprint(options.port)
		if commandKind == scpKind {
			// scp uses -P instead of -p (-p means preserve).
			args = append(args, "-P", port)
		} else {
			args = append(args, "-p", port)
		}
	}
	return args
}

// Command implements Client.Command.
func (c *OpenSSHClient) Command(host string, command []string, options *Options) *Cmd {
	args := opensshOptions(options, sshKind)
	args = append(args, host)
	if len(command) > 0 {
		args = append(args, command...)
	}
	bin, args := sshpassWrap("ssh", args)
	logger.Debugf("running: %s %s", bin, utils.CommandString(args...))
	return &Cmd{impl: &opensshCmd{exec.Command(bin, args...)}}
}

// Copy implements Client.Copy.
func (c *OpenSSHClient) Copy(targets, extraArgs []string, userOptions *Options) error {
	var options Options
	if userOptions != nil {
		options = *userOptions
		options.allocatePTY = false // doesn't make sense for scp
	}
	args := opensshOptions(&options, scpKind)
	args = append(args, extraArgs...)
	args = append(args, targets...)
	bin, args := sshpassWrap("scp", args)
	cmd := exec.Command(bin, args...)
	var stderr bytes.Buffer
	cmd.Stderr = &stderr
	logger.Debugf("running: %s %s", bin, utils.CommandString(args...))
	if err := cmd.Run(); err != nil {
		stderr := strings.TrimSpace(stderr.String())
		if len(stderr) > 0 {
			err = fmt.Errorf("%v (%v)", err, stderr)
		}
		return err
	}
	return nil
}

type opensshCmd struct {
	*exec.Cmd
}

func (c *opensshCmd) SetStdio(stdin io.Reader, stdout, stderr io.Writer) {
	c.Stdin, c.Stdout, c.Stderr = stdin, stdout, stderr
}

func (c *opensshCmd) StdinPipe() (io.WriteCloser, io.Reader, error) {
	wc, err := c.Cmd.StdinPipe()
	if err != nil {
		return nil, nil, err
	}
	return wc, c.Stdin, nil
}

func (c *opensshCmd) StdoutPipe() (io.ReadCloser, io.Writer, error) {
	rc, err := c.Cmd.StdoutPipe()
	if err != nil {
		return nil, nil, err
	}
	return rc, c.Stdout, nil
}

func (c *opensshCmd) StderrPipe() (io.ReadCloser, io.Writer, error) {
	rc, err := c.Cmd.StderrPipe()
	if err != nil {
		return nil, nil, err
	}
	return rc, c.Stderr, nil
}

func (c *opensshCmd) Kill() error {
	if c.Process == nil {
		return fmt.Errorf("process has not been started")
	}
	return c.Process.Kill()
}
<|endoftext|>


<commit_before>package storage

import (
	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
)

var DB *sqlx.DB
var DBAvailable int = 0

func InitDB(conn_string string) error {
	var err error
	if DB, err = sqlx.Open("postgres", conn_string); err == nil {
		if err := DB.Ping(); err == nil {
			DBAvailable = 1
			_onReady() // launch functions dependant on DBs readiness
		} else {
			DBAvailable = -1
			return err // Error at DB.Ping() call
		}
	} else {
		return err // Error at sqlx.Open() call
	}
	return nil
}

var onReady []func() = []func(){}

func OnReady(initdb func()) {
	onReady = append(onReady, initdb)
}

func _onReady() {
	for _, fn := range onReady {
		go fn() // launch functions dependant on DBs readiness
	}
}
<commit_msg>I dun remember why it was there<commit_after>package storage

import (
	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
)

var DB *sqlx.DB

func InitDB(conn_string string) error {
	var err error
	if DB, err = sqlx.Open("postgres", conn_string); err == nil {
		if err := DB.Ping(); err == nil {
			_onReady() // launch functions dependant on DBs readiness
		} else {
			return err // Error at DB.Ping() call
		}
	} else {
		return err // Error at sqlx.Open() call
	}
	return nil
}

var onReady []func() = []func(){}

func OnReady(initdb func()) {
	onReady = append(onReady, initdb)
}

func _onReady() {
	for _, fn := range onReady {
		go fn() // launch functions dependant on DBs readiness
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"database/sql"
	"flag"
	"fmt"
	"io"
	"os"
	"runtime"
	"strings"
	"time"

	"github.com/juju/errors"
	"github.com/ngaut/log"
	"github.com/peterh/liner"
	"github.com/pingcap/tidb"
	"github.com/pingcap/tidb/terror"
	"github.com/pingcap/tidb/util/printer"
)

var (
	logLevel = flag.String("L", "error", "log level")
	store    = flag.String("store", "goleveldb", "the name for the registered storage, e.g. memory, goleveldb, boltdb")
	dbPath   = flag.String("dbpath", "test/test", "db path")

	line        *liner.State
	historyPath = "/tmp/tidb_interpreter"
)

func openHistory() {
	if f, err := os.Open(historyPath); err == nil {
		line.ReadHistory(f)
		f.Close()
	}
}

func saveHistory() {
	if f, err := os.Create(historyPath); err == nil {
		line.WriteHistory(f)
		f.Close()
	}
}

func executeLine(tx *sql.Tx, txnLine string) error {
	start := time.Now()
	if tidb.IsQuery(txnLine) {
		rows, err := tx.Query(txnLine)
		elapsed := time.Since(start).Seconds()
		if err != nil {
			return errors.Trace(err)
		}
		defer rows.Close()
		cols, err := rows.Columns()
		if err != nil {
			return errors.Trace(err)
		}

		values := make([][]byte, len(cols))
		scanArgs := make([]interface{}, len(values))
		for i := range values {
			scanArgs[i] = &values[i]
		}

		var datas [][]string
		for rows.Next() {
			err := rows.Scan(scanArgs...)
			if err != nil {
				return errors.Trace(err)
			}

			data := make([]string, len(cols))
			for i, value := range values {
				if value == nil {
					data[i] = "NULL"
				} else {
					data[i] = string(value)
				}
			}

			datas = append(datas, data)
		}

		// For `cols` and `datas[i]` always has the same length,
		// no need to check return validity.
		result, _ := printer.GetPrintResult(cols, datas)
		fmt.Printf("%s", result)

		switch len(datas) {
		case 0:
			fmt.Printf("Empty set")
		case 1:
			fmt.Printf("1 row in set")
		default:
			fmt.Printf("%v rows in set", len(datas))
		}
		fmt.Printf(" (%.2f sec)\n", elapsed)
		if err := rows.Err(); err != nil {
			return errors.Trace(err)
		}
	} else {
		// TODO: last insert id
		res, err := tx.Exec(txnLine)
		elapsed := time.Since(start).Seconds()
		if err != nil {
			return errors.Trace(err)
		}
		cnt, err := res.RowsAffected()
		if err != nil {
			return errors.Trace(err)
		}
		switch cnt {
		case 0, 1:
			fmt.Printf("Query OK, %d row affected", cnt)
		default:
			fmt.Printf("Query OK, %d rows affected", cnt)
		}
		fmt.Printf(" (%.2f sec)\n", elapsed)
	}
	return nil
}

func mayExit(err error, l string) bool {
	if terror.ErrorEqual(err, liner.ErrPromptAborted) || terror.ErrorEqual(err, io.EOF) {
		fmt.Println("\nBye")
		saveHistory()
		return true
	}
	if err != nil {
		log.Fatal(errors.ErrorStack(err))
	}
	return false
}

func readStatement(prompt string) (string, error) {
	var ret string
	for {
		l, err := line.Prompt(prompt)
		if err != nil {
			return "", err
		}
		if strings.HasSuffix(l, ";") == false {
			ret += l + "\n"
			prompt = "   -> "
			continue
		}
		return ret + l, nil
	}
}

func main() {
	printer.PrintTiDBInfo()

	flag.Parse()
	log.SetLevelByString(*logLevel)
	// support for signal notify
	runtime.GOMAXPROCS(runtime.NumCPU())

	line = liner.NewLiner()
	defer line.Close()

	line.SetCtrlCAborts(true)
	openHistory()

	// For interpreter, we don't must run DDL quickly with remote storage too.
	tidb.SetSchemaLease(100 * time.Millisecond)

	mdb, err := sql.Open(tidb.DriverName, *store+"://"+*dbPath)
	if err != nil {
		log.Fatal(errors.ErrorStack(err))
	}

	for {
		l, err := readStatement("tidb> ")
		if mayExit(err, l) {
			return
		}
		line.AppendHistory(l)

		// if we're in transaction
		if strings.HasPrefix(l, "BEGIN") || strings.HasPrefix(l, "begin") {
			tx, err := mdb.Begin()
			if err != nil {
				log.Error(errors.ErrorStack(err))
				continue
			}
			for {
				txnLine, err := readStatement(">> ")
				if mayExit(err, txnLine) {
					return
				}
				line.AppendHistory(txnLine)

				if !strings.HasSuffix(txnLine, ";") {
					txnLine += ";"
				}

				if strings.HasPrefix(txnLine, "COMMIT") || strings.HasPrefix(txnLine, "commit") {
					err := tx.Commit()
					if err != nil {
						log.Error(errors.ErrorStack(err))
						tx.Rollback()
					}
					break
				}
				// normal sql statement
				err = executeLine(tx, txnLine)
				if err != nil {
					log.Error(errors.ErrorStack(err))
					tx.Rollback()
					break
				}
			}
		} else {
			tx, err := mdb.Begin()
			if err != nil {
				log.Error(errors.ErrorStack(err))
				continue
			}
			err = executeLine(tx, l)
			if err != nil {
				log.Error(errors.ErrorStack(err))
				tx.Rollback()
			} else {
				tx.Commit()
			}
		}
	}
}
<commit_msg>interpreter: add lease flag.<commit_after>// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"database/sql"
	"flag"
	"fmt"
	"io"
	"os"
	"runtime"
	"strings"
	"time"

	"github.com/juju/errors"
	"github.com/ngaut/log"
	"github.com/peterh/liner"
	"github.com/pingcap/tidb"
	"github.com/pingcap/tidb/terror"
	"github.com/pingcap/tidb/util/printer"
)

var (
	logLevel = flag.String("L", "error", "log level")
	store    = flag.String("store", "goleveldb", "the name for the registered storage, e.g. memory, goleveldb, boltdb")
	dbPath   = flag.String("dbpath", "test/test", "db path")
	lease    = flag.Int("lease", 300, "schema lease seconds, very dangerous to change only if you know what you do")

	line        *liner.State
	historyPath = "/tmp/tidb_interpreter"
)

func openHistory() {
	if f, err := os.Open(historyPath); err == nil {
		line.ReadHistory(f)
		f.Close()
	}
}

func saveHistory() {
	if f, err := os.Create(historyPath); err == nil {
		line.WriteHistory(f)
		f.Close()
	}
}

func executeLine(tx *sql.Tx, txnLine string) error {
	start := time.Now()
	if tidb.IsQuery(txnLine) {
		rows, err := tx.Query(txnLine)
		elapsed := time.Since(start).Seconds()
		if err != nil {
			return errors.Trace(err)
		}
		defer rows.Close()
		cols, err := rows.Columns()
		if err != nil {
			return errors.Trace(err)
		}

		values := make([][]byte, len(cols))
		scanArgs := make([]interface{}, len(values))
		for i := range values {
			scanArgs[i] = &values[i]
		}

		var datas [][]string
		for rows.Next() {
			err := rows.Scan(scanArgs...)
			if err != nil {
				return errors.Trace(err)
			}

			data := make([]string, len(cols))
			for i, value := range values {
				if value == nil {
					data[i] = "NULL"
				} else {
					data[i] = string(value)
				}
			}

			datas = append(datas, data)
		}

		// For `cols` and `datas[i]` always has the same length,
		// no need to check return validity.
		result, _ := printer.GetPrintResult(cols, datas)
		fmt.Printf("%s", result)

		switch len(datas) {
		case 0:
			fmt.Printf("Empty set")
		case 1:
			fmt.Printf("1 row in set")
		default:
			fmt.Printf("%v rows in set", len(datas))
		}
		fmt.Printf(" (%.2f sec)\n", elapsed)
		if err := rows.Err(); err != nil {
			return errors.Trace(err)
		}
	} else {
		// TODO: last insert id
		res, err := tx.Exec(txnLine)
		elapsed := time.Since(start).Seconds()
		if err != nil {
			return errors.Trace(err)
		}
		cnt, err := res.RowsAffected()
		if err != nil {
			return errors.Trace(err)
		}
		switch cnt {
		case 0, 1:
			fmt.Printf("Query OK, %d row affected", cnt)
		default:
			fmt.Printf("Query OK, %d rows affected", cnt)
		}
		fmt.Printf(" (%.2f sec)\n", elapsed)
	}
	return nil
}

func mayExit(err error, l string) bool {
	if terror.ErrorEqual(err, liner.ErrPromptAborted) || terror.ErrorEqual(err, io.EOF) {
		fmt.Println("\nBye")
		saveHistory()
		return true
	}
	if err != nil {
		log.Fatal(errors.ErrorStack(err))
	}
	return false
}

func readStatement(prompt string) (string, error) {
	var ret string
	for {
		l, err := line.Prompt(prompt)
		if err != nil {
			return "", err
		}
		if strings.HasSuffix(l, ";") == false {
			ret += l + "\n"
			prompt = "   -> "
			continue
		}
		return ret + l, nil
	}
}

func main() {
	printer.PrintTiDBInfo()

	flag.Parse()
	log.SetLevelByString(*logLevel)
	// support for signal notify
	runtime.GOMAXPROCS(runtime.NumCPU())

	line = liner.NewLiner()
	defer line.Close()

	line.SetCtrlCAborts(true)
	openHistory()

	tidb.SetSchemaLease(time.Duration(*lease) * time.Second)

	mdb, err := sql.Open(tidb.DriverName, *store+"://"+*dbPath)
	if err != nil {
		log.Fatal(errors.ErrorStack(err))
	}

	for {
		l, err := readStatement("tidb> ")
		if mayExit(err, l) {
			return
		}
		line.AppendHistory(l)

		// if we're in transaction
		if strings.HasPrefix(l, "BEGIN") || strings.HasPrefix(l, "begin") {
			tx, err := mdb.Begin()
			if err != nil {
				log.Error(errors.ErrorStack(err))
				continue
			}
			for {
				txnLine, err := readStatement(">> ")
				if mayExit(err, txnLine) {
					return
				}
				line.AppendHistory(txnLine)

				if !strings.HasSuffix(txnLine, ";") {
					txnLine += ";"
				}

				if strings.HasPrefix(txnLine, "COMMIT") || strings.HasPrefix(txnLine, "commit") {
					err := tx.Commit()
					if err != nil {
						log.Error(errors.ErrorStack(err))
						tx.Rollback()
					}
					break
				}
				// normal sql statement
				err = executeLine(tx, txnLine)
				if err != nil {
					log.Error(errors.ErrorStack(err))
					tx.Rollback()
					break
				}
			}
		} else {
			tx, err := mdb.Begin()
			if err != nil {
				log.Error(errors.ErrorStack(err))
				continue
			}
			err = executeLine(tx, l)
			if err != nil {
				log.Error(errors.ErrorStack(err))
				tx.Rollback()
			} else {
				tx.Commit()
			}
		}
	}
}
<|endoftext|>